home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 …SCII & the Runetime Code / ADC Developer CD (1992-07) (''Butch ASCII And The Runtime Code'')_iso / Dev.CD 199207.iso / Development Platforms / Apple II / DTS Apple II Sample Code / IR 2.0 / Source Code / IR / RequestProc.aii < prev   
Encoding:
Text File  |  1992-02-25  |  110.1 KB  |  4,737 lines  |  [TEXT/MPS ]

  1. *******************************************************************************
  2. * IR Request Procedure
  3. *
  4. * (C)  Copyright Apple Computer, Inc. 1991-1992
  5. * All rights reserved.
  6. *
  7. * by Matt Deatherage
  8. * October 26, 1991
  9. *
  10. * This file contains the code for IR's request procedures, which are what
  11. * actually do all the work in the new, kinder, gentler, 6.0    version of IR.
  12. *
  13. * Modification History:
  14. *
  15. * Version    Author
  16. *
  17. *
  18. * 2.0a1    Matt Deatherage    11/18/91 (Happy 25th birthday...)
  19. *
  20. * First version of this file.
  21. *
  22. *
  23. * 2.0a2    Matt Deatherage    11/25/91
  24. *
  25. * 2.0a1 built, 2.0a2 is the first release attempt.  Lots and lots of 
  26. * changes to make it work.  Mostly little bug fixes not worth mentioning.
  27. * NDA section almost completely rewritten because the stupid Desk Manager
  28. * doesn't add DA reference numbers to the menu item at InstallNDA time like
  29. * any reasonable person would assume.  Now we have to extract the address
  30. * of the init routine and call it ourselves, switching in the direct page and
  31. * stack we got from InitialLoad2 (or that we allocated) instead of asking
  32. * CallDeskAcc to send the kiss of life.  This is because the stupid (did I
  33. * say that already?) Desk Manager doesn't put the necessary ID number of an
  34. * NDA into the header until FixAppleMenu time, and for compatibility I can't
  35. * blindly call FixAppleMenu.  (This is a request proc; the Menu Manager may
  36. * not even be started for me to allocate a dummy duplicate Apple menu, which
  37. * might not work anyway.)
  38. *
  39. * Preferences reworked because of the new NDA strategy.  Both NDA equates
  40. * and their meanings changed.  Now the two options are "Open existing NDAs,"
  41. * which opens an NDA if it's a duplicate and duplicates aren't supposed
  42. * to be here; and "Open new NDAs" which does the Apple menu futz and opens
  43. * the NDA window for newly installed DAs.  For a compatibility option, if
  44. * this bit is _not_ set the DA is just installed and given an initial
  45. * Shutdown code, but not a startup call, it's not added to the Apple menu
  46. * and it's not opened.  Control titles and ID equates changed to reflect
  47. * the new changes.
  48. *
  49. * Since it turns out we'll have to queue up user IDs not only for killing
  50. * some Finder Extensions, but also for sending finderSaysHello to anything
  51. * we've started when we get the next finderSaysIdle message, I added a new
  52. * mechanism to keep lists of user IDs in handles.  Some supporting routines
  53. * add IDs to the queues and return pointers or handles to them.  This is the
  54. * mechanism we use for these things now.  Added routines AddIDToQueue,
  55. * GetQueuePtr, GetQueueHandle, IRSeesIdle (also added to the request table).
  56. * Changed KillMyFEs to use the queues instead of hard-coded built-in buffer
  57. * space.
  58. *
  59. * Added new _DebugStr and _SetMileStone macros to the beginning of this file
  60. * for debugging use.  The ones on M16.GSBug are kind of brain-dead; they're
  61. * just regular tool call macros.  The ones in this file let you embed the
  62. * string as the argument to the macro, like "_DebugStr 'This is a test'".
  63. * They save A,X,Y and P and generate no code if DebugSymbols is zero, just
  64. * like the M16.Debug name and procname macros we also use.
  65. *
  66. *
  67. * 2.0a3    Matt Deatherage    12/12/91 (Happy birthday, Dad...)
  68. *
  69. * CheckFileAuxType had two missing iny instructions, and Dave suggested
  70. * rewriting it once I didn't have [<DP],y instructions on the brain.  He's
  71. * right -- lda table,x works much nicer.
  72. *
  73. * IRReturnsPreferences was putting the preferences in the _second_ word of
  74. * the buffer, and RequestProc was happily overwriting them with the $0000 for
  75. * no error.  They're now returned in the third word, like the header files and
  76. * the comments say.
  77. *
  78. * IRGetsAnOpen no longer whooshes back into the icon if you're opening an
  79. * NDA.  It should only refuse to whoosh if the NDA wasn't opened, but right now
  80. * it doesn't get that information back from askIRToInstall.
  81. *
  82. * 2.0a4    Matt Deatherage    12/18/91
  83. *
  84. * Several optimizations made at Dave Lyons' suggestion.  Stuff like changing
  85. * "lda localPrefs, ora #preference, sta LocalPrefs" to "lda #preference, tsb
  86. * LocalPrefs".  Some "pei" instructions inserted.  Some "stz"s added where
  87. * they didn't used to be possible due to addressing modes.  Little things.
  88. *
  89. * IRGetsAnOpen was returning irError codes in the second word of the dataOut
  90. * buffer, even though it's reserved for finderSaysBeforeOpen and
  91. * finderSaysOpenFailed.  Oops.  Now fixed.
  92. *
  93. * IRGetsToWork was only checking the low bit of OS_KIND instead of checking
  94. * for a value of $01.  Now it's right.
  95. *
  96. * Duplicate-checking code was potentially calling UserShutDown on CDAs or NDAs
  97. * that accepted the srqGoAway code without removing them from the Desk Manager's
  98. * lists.  Now they're removed, and GS/OS drivers are never given srqGoAway
  99. * codes since they can't be removed (even if some driver does accept the
  100. * srqGoAway code).  This entailed major changes to UserIDToDAID (formerly
  101. * UserIDToNDAID) -- it now counts up from 1 looking for DAs instead of
  102. * assuming there were so many and counting down.
  103. *
  104. * Some NDAs are faithfully saving the current cursor when they get an open
  105. * call and restoring the cursor to that when they're closed.  This isn't
  106. * necessarily a swift idea, because the application's idea of what the cursor
  107. * should be when the NDA is finally closed may not be related at all to what
  108. * the cursor was then the DA was opened.  Nevertheless, OpenNDAByUserID now
  109. * calls InitCursor before opening the NDA just in case.
  110. *
  111. * IRGetsAnOpen no longer adds things to the NeedsHello queue if askIRToInstall
  112. * didn't accept the request.  It does not reject the open request right now;
  113. * in a future version it will display an alert saying why the thing couldn't
  114. * be installed.
  115. *
  116. * IRGetsToWork isn't returning errors for requests it doesn't accept anymore.
  117. * It now accepts the request and returns an IR result code.
  118. *
  119. * DoDrivers no longer loses Memory Manager errors when allocating the handle
  120. * for the DIB structure fails.
  121. *
  122. * Queue handles are no longer unlocked during calls to SendRequest.
  123. *
  124. * GetPrefsFromDisk now has the same common sense PutPrefsToDisk does -- that
  125. * is, it closes the file when its done with it.
  126. *
  127. * The handle for the preferences pathname is now fixed and no special
  128. * memory because it never moves.  This may change when MakePrefsPath works
  129. * correctly over AppleShare booting.
  130. *
  131. * GetQueuePtr/Handle now uses QueueTable,x (or y) addressing.
  132. *
  133. * Still no alert or error windows for the standard IR errors, or comments
  134. * identifying the machine-generated control source, or proper preference
  135. * file placing when booting over AppleShare.  Stay tuned.
  136. *
  137. * 2.0b1    Matt Deatherage    2/19/92
  138. *
  139. * RESOURCE FORK ADDED!  Wow.  An INIT with a resource fork; what stupid idea
  140. * will I try next.  To implement this:
  141. *
  142. * %  Added GiveMeMyFork to make our resource fork available.  If our resource
  143. *    file is open, it just sets the current resource application to IR.  If
  144. *    not, it starts the Resource Manager and opens our resource fork.  The
  145. *    old resource application is stored on the stack frame so we can be
  146. *    reentrant.
  147. *
  148. * %  Significant changes to IRDoesPreferences.  Now gets the alert string,
  149. *    window template and 320/640 rectangles from resources.  They're modified
  150. *    in memory and passed along to the toolbox as appropriate.
  151. *
  152. * %  Changed IRStartsUp to get the version number and the init icon from the
  153. *    resource fork.  Stores the result from VersionString in semi-permanent
  154. *    storage so we don't have to call VersionString more than once.
  155. *
  156. * %  Added IRNotifyProc so we can close our resource file and zero out our
  157. *    flags that mark it as open.  If we just let the Resource Manager do this
  158. *    for us, we never get told that our resource file gets closed.
  159. *
  160. * IR now behaves responsibly when you install it and IR is already installed.
  161. * Specifically, IRStartsUp finds the ID of any existing IRs (by sending the
  162. * askIRAreYouThere request) and adds it to a new IRQueue.  IRSaysIRHere now
  163. * doesn't respond if we're not done starting up, so we don't answer our own
  164. * request.  The ID of any old IR gets added to a queue that the new IR keeps
  165. * around.  The newly-installed IR tries to kill everything in the IRQueue
  166. * every chance it gets.  The old IR won't go away if it has anything in the
  167. * NeedsHelloQueue; once it can go away, the new IR kills it.
  168. *
  169. * To facilitate all this, KillMyFEs is now 'KillQueueEntries' that sends
  170. * srqGoAway and calls UserShutDown on every ID in that queue, leaving the
  171. * items that didn't go away in the queue.  This is more generic and works
  172. * with the kill-old-IRs mechanism.
  173. *
  174. * Before moving IR's icon to the resource fork, I fixed the mask so the
  175. * background doesn't show through where I didn't intend it to.
  176. *
  177. * Changed IRSaysIRHere to return the user ID in the second word of the
  178. * output buffer instead of returning nothing.
  179. *
  180. * 2.0b2    Matt Deatherage    2/20/92
  181. *
  182. * Changed MakePrefsPath to (finally) work correctly and put the IR.Preferences
  183. * file in the AppleShare user folder if IR is on an AppleShare volume.
  184. *
  185. * Remembered to delete the Notification procedure in IRGoesAway.
  186. *
  187. * Changed IRGetsToWork so we don't call RemoveXDA before we send the srqGoAway
  188. * request -- things that don't accept the request shouldn't be removed!
  189. *
  190. * Added DoAlertWindow for easy notification of problem areas, and call it
  191. * when we try to install Finder Extensions when not in the Finder, and when
  192. * irDuplicateWontDie would be returned (to ask if another copy is OK).  To
  193. * facilitate this, it makes sense for IRBidsFinderFarewell to actually zero
  194. * out the FSHDataIn parameter we use to see if we're in the Finder or not,
  195. * so now it does.
  196. *
  197. * Something's still wrong with the notification procedure; when IR is removed
  198. * with srqGoAway, the system crashes on random OS events.  I don't have much
  199. * of a clue at this point -- it looks OK to me.  Haven't spent lots of time
  200. * debugging it yet.
  201. *
  202. * 2.0b3    Matt Deatherage    2/21/92
  203. *
  204. * Changed copyright dates to reflect reality.
  205. *
  206. * DelNotifyProc wasn't behaving because I was passing the address of the code
  207. * instead of the address of the notify proc header.  Oops.  Fixed.
  208. *
  209. * Fixed several errors in comments and typos throughout the source.
  210. *
  211. * Changed GiveMeMyFork to take no action if we've already changed the current
  212. * resource app, avoiding a possible reentrancy problem if two routines inside
  213. * IR called GiveMeMyFork in response to the same user SendRequest.
  214. *
  215. * Changed DoAlertWindow to return $FFFF instead of $0000 if something went
  216. * wrong, since $0000 is a valid button number.
  217. *
  218. * Changed all instances of "lda #denyRequest, sta <result" to "stz <result"
  219. * because it really, really bugs Dave that I wouldn't use stz even when
  220. * I think the symbolic version is easier to understand.
  221. *
  222. * IRRequestProc now accepts no requests if the stack is in page one, since
  223. * our stack usage combined with any tools we call is likely to make the
  224. * poor thing overflow.
  225. *
  226. * Discovered that askIRToInstall actually was always using your overriding
  227. * preferences and not just if you set bit zero, as was originally designed.
  228. * Fixed this to work correctly by keeping a third copy of the preferences
  229. * in storage, valid only through askIRToInstall.
  230. *
  231. * In conjunction with this, changed IRGetsToWork to increment and decrement
  232. * the IRBusyFlag.  Changed IRGetsAnOpen to decrement the busy flag instead
  233. * of stz'ing it to be more polite.
  234. *
  235. * We now no longer kill things that accept srqGoAway but return user ID of
  236. * zero, because we never were supposed to.  Oops.
  237. *
  238. * In reshuffling the RemoveXDA code in b2, accidentally left an inaccurate
  239. * label in @RemoveCDA (inside IRGetsToWork), which made it repeat some stuff
  240. * in a not useful fashion.  Fixed.
  241. *
  242. * Changed DoInitsFEs to set the init/FE data bank register to $FF (like
  243. * GS/OS does) instead of to the init/FE code bank.  Yes, badly-written inits
  244. * will crash faster this way, but we want init authors to find that out.
  245. *
  246. * Instead of refusing srqGoAway, we now accept it with user ID zero to say
  247. * that we can't go away.  Dave says this is more correcter.
  248. *
  249. * When sending finderSaysGoodbye to our Finder Extensions, we now no longer
  250. * send with "stopAfterOne" because they might have multiple requests installed
  251. * with the same user ID.
  252. *
  253. * IRSetsPreferences now masks out bit zero before storing in LocalPrefs as
  254. * well as before putting them to disk.
  255. *
  256. * MakePrefsPath correctly preserves the error code after the call to
  257. * LGetPathname2 now.
  258. *
  259. * Changed resource loading code to release resources when we're done using
  260. * them (unless we pass them to the Toolbox by ID).  Changed pointer math
  261. * on some resources to not worry about bank crossing and changed the resource
  262. * attributes to specify "noBankCross" to justify this.
  263. *
  264. * IRDoesPreferences now exits gracefully if the Window Manager isn't started
  265. * up, so it won't blow up if you call it from Not The Desktop.
  266. *
  267. * 2.0b4    Matt Deatherage    2/23/92
  268. *
  269. * If, in the process of installing a new thing, we have to kill the old thing,
  270. * and if we're also in the Finder, we should send finderSaysGoodbye before
  271. * sending srqGoAway.  We haven't been doing that.  Now we are.  This is
  272. * slightly weird, because it means that if something _can't_ go away, we're
  273. * now sending it finderSaysGoodbye anyway and it will be "invisible" to the
  274. * user (no Extras menu items, etc.), but still in memory.  Even weirder, it
  275. * will magically "reappear" the next time they launch Finder, giving them
  276. * perhaps multiple copies of it.  People who find this behavior extremely
  277. * annoying should probably turn on the "Always remove old one" and "Tell me
  278. * about problems" preferences so IR will tell you when this might happen.
  279. *
  280. * But no, it gets worse.  We can't send finderSaysGoodbye from within 
  281. * IRGetsToWork (always) because we're often there from finderSaysBeforeOpen
  282. * (or OpenFailed), in which case the Finder can't respond to whatever the
  283. * thing we're talking to wants it to do (like remove menu items, etc.).  So,
  284. * unless we were called from our own Idle procedure (so we're _sure_ it's safe
  285. * to do these things, we queue up things to install in our own Idle procedure
  286. * and at Idle time, we just call askIRToInstall again.  IRGetsToWork doesn't
  287. * do anything dangerous unless our global "it's idle time!" flag is set.
  288. * In that case only, it sends finderSaysGoodbye to duplicate extensions and
  289. * sends all newly-installed things finderSaysHello before returning.
  290. *
  291. * 2.0f1    Matt Deatherage    2/25/92  (time flies with deadlines...)
  292. *
  293. * IRGetsToWork was setting the busy flag but not checking it.  If you'd
  294. * ever managed to call IRGetsToWork from within an IRGetsToWork, it would
  295. * blow away the temporary preferences.  However, since that was the only
  296. * reentrancy problem, TempPrefs is now on the stack frame and IRGetsToWork
  297. * no longer increments or decrements IRBusyFlag.  IRGetsAnOpen does, though.
  298. *
  299. * I was loading the rAlertString resource for the "About" alert and replacing
  300. * the rectangle in the string with the correct rectangle before ever calling
  301. * AlertWindow.  But since I was still passing the reference by resource, the
  302. * Window Manager was disposing of the rAlertString resource and reloading it
  303. * if you clicked on the version number again.  The second time it got the
  304. * wrong rectangle.  There are two ways around this -- either detach the
  305. * resource and do everything by handle, or make sure the resource doesn't go
  306. * away until we're definitely done with it.  I choose the latter -- I use the
  307. * new AlertWindow bit to make AlertWindow keep the resource at purge level 3.
  308. * I set the "locked" bit on the resource to keep it from being purged, and I
  309. * explictly release the resource at the end of IRDoesPreferences.  This works
  310. * much better.
  311. *
  312. * When I fixed the problem that the local preferences could be stored with
  313. * bit zero set, I accidentally cleared it too soon, so it was never getting
  314. * set and PutPrefsToDisk wasn't getting called, even on a "save" in the
  315. * preferences dialog.  Now fixed.
  316. *
  317. * The window template for the preferences window was being loaded unlocked
  318. * (so it can be purged) and I was making toolbox calls that could move
  319. * memory after dereferencing it but before using it.  The window resource
  320. * is now marked "locked" in the resource file, and before leaving the
  321. * IRDoesPreferences routine, I reload the resource (returning the same
  322. * locked handle) and release it to level $FFFF, disposing it instantly.
  323. *
  324. * At Dave's request, if you have your preferences set to "Always kill old
  325. * copies" and you encounter one that won't go away, pressing the option key
  326. * while clicking "Install another copy" makes IR forcibly shut down the old
  327. * one anyway.  This is very dangerous unless you know what you're doing so
  328. * it may or may not make it into the Read.me file.  Aren't you glad you
  329. * read all these comments?
  330. *
  331. * askIRAreYouThere (IRSaysIRHere) now returns the version longword from our
  332. * resource fork in +004 through +007 of the dataOut buffer.  This is kept from
  333. * boot time in the IRVersion global variable so we don't have to do it again.
  334. *
  335. * MakePrefsPath now creates the file in the same directory as the IR
  336. * file even on AppleShare if GetUserPath returns an error.  This helps in
  337. * the slightly-pathological-which-is-why-I-use-it case of launching it from
  338. * a server that has no user volume, as long as you have write privileges
  339. * to the IR folder.  (My server isn't an Apple II boot server, but the same
  340. * is true for System 7 File Sharing.)
  341. *
  342. * IRGetsToWork now actually respects the irNoDuplicates flag -- if it's clear,
  343. * it doesn't mess with trying to remove or shut down duplicates at all.  It
  344. * bypasses all that stuff and goes directly to loading a new copy.
  345. *
  346. * IRGoesAway was duplicating the functionality of IRBidsFinderFarewell --
  347. * which means we could be removing our own Finder Extras menu item more
  348. * than once.  Since we're supposed to get finderSaysGoodbye before
  349. * srqGoAway, the duplicate code in srqGoAway is now gone.
  350. *
  351. * There's a significant problem in trying to kill duplicate anythings that
  352. * install Finder request procedures, by design.  If we have to try to kill
  353. * a duplicate while in the Finder, we're required to send the duplicate a
  354. * finderSaysGoodbye request before we send srqGoAway.  However, if the original
  355. * can't accept srqGoAway for whatever reason, it's already seen our
  356. * finderSaysGoodbye request.  It will eventually get a second one, either from
  357. * the Finder or from us again if someone tries to double-click that file
  358. * again and irNoDuplicates is set.  This can cause serious problems.  For
  359. * example, EasyMount zeroes out its Extras menu item ID global variable,
  360. * and if it gets a second finderSaysGoodbye code, it makes a request to
  361. * tellFinderRemoveFromExtras with a zero menu item ID.  This makes the Finder
  362. * remove the "About the Finder..." menu item.  Ack.
  363. *
  364. * There really isn't a way around this -- even keeping a list of all the things
  365. * I have that I couldn't kill won't prevent the Finder from sending duplicate
  366. * finderSaysGoodbye codes.  The only options are:
  367. *
  368. * a)  Don't send finderSaysGoodbye before srqGoAway -- not acceptable.
  369. * b)  Invent an srqCanYouGoAway code -- too late for EasyMount and others.
  370. * c)  Require everyone to accept multiple finderSaysGoodbye requests without
  371. *     causing damage -- too late for EasyMount
  372. * d)  Require everyone to always act on srqGoAway -- not feasible.
  373. *
  374. * So, the real compromise solution is a combination of c) and d).  We'll document
  375. * that your Finder Extension must either always act on srqGoAway or must accept
  376. * multiple finderSaysGoodbye requests harmlessly.  Failure to do so is now
  377. * chalked up as a "bug" in EasyMount.  To work around this from a user
  378. * standpoint, set the "Always kill duplicates" radio button and hold down the
  379. * option key when clicking "Install another copy."  I guess this does have to
  380. * go into the documentation now.
  381. *
  382. * 2.0    Matt Deatherage    02/25/92
  383. * Changed DebugSymbols to zero to remove all procedure names and any left over
  384. * _DebugStr or _SetMileStone macros.
  385. *
  386. *******************************************************************************
  387.  
  388.     INCLUDE 'E16.IR'
  389.     INCLUDE 'M16.Util2'
  390.     INCLUDE 'E16.Locator'
  391.     INCLUDE 'M16.Locator'
  392.     INCLUDE 'M16.MiscTool'
  393.     INCLUDE 'E16.GSOS'
  394.     INCLUDE 'M16.GSOS'
  395.     INCLUDE 'E16.Loader'
  396.     INCLUDE 'M16.Loader'
  397.     INCLUDE 'M16.Window'
  398.     INCLUDE 'E16.Window'
  399.     INCLUDE 'M16.Control'
  400.     INCLUDE 'M16.Debug'
  401.     INCLUDE 'E16.Event'
  402.     INCLUDE 'M16.Memory'
  403.     INCLUDE 'M16.Desk'
  404.     INCLUDE 'E16.Desk'
  405.     INCLUDE 'M16.QDAux'
  406.     INCLUDE 'E16.Finder'
  407.     INCLUDE 'M16.QuickDraw'
  408.     INCLUDE 'M16.Menu'
  409.     INCLUDE 'M16.Resources'
  410.     INCLUDE 'E16.Resources'
  411.     
  412. *******************************************************************************
  413. *
  414. * Revised _DebugStr and _SetMileStone macros for our use
  415. *
  416. *******************************************************************************
  417.  
  418.      MACRO
  419. &lab     _DebugStr &s
  420. &lab 
  421.     if DebugSymbols<>0 then
  422.     php
  423.     pha
  424.     phx
  425.     phy    ; save the registers
  426.     pea @string>>16
  427.     pea |@string
  428.          ldx #$09FF
  429.          jsl $E10000
  430.     ply
  431.     plx
  432.     pla
  433.     plp
  434.     bra @pastString
  435. @String    str &s
  436. @PastString
  437.     endif
  438.     mend
  439.     
  440.      MACRO
  441. &lab     _SetMileStone &s
  442. &lab 
  443.     if DebugSymbols<>0 then
  444.     php
  445.     pha
  446.     phx
  447.     phy    ; save the registers
  448.     pea @string>>16
  449.     pea |@string
  450.          ldx #$0AFF
  451.          jsl $E10000
  452.     ply
  453.     plx
  454.     pla
  455.     plp
  456.     bra @pastString
  457. @String    str &s
  458. @PastString
  459.     endif
  460.     mend
  461.  
  462.  
  463. *******************************************************************************
  464. *
  465. * Equates for within the request procedures
  466. *
  467. *******************************************************************************
  468.  
  469. DebugSymbols    equ 0    ; for inline procedure names
  470.  
  471.     DefineStack
  472.  
  473. ;
  474. ; Stuff that we allocate as local variables in the request proc
  475.  
  476.  
  477.  
  478. PrefsWindPtr    Long    ; pointer to preferences window when up
  479. MyDPageFlag    Word    ; flag to indicate I allocated bank zero memory
  480. FilePointer    Long    ; GS/OS string pointer to the file we're going to
  481.         ; load
  482. TempPrefs    Word    ; temporary preferences for IRGetsToWork
  483. OldResourceApp    Word    ; previous resource application
  484. ThisInitID    Word    ; user ID of the thing we're working on
  485. StartAddress    Long    ; address where the thing got loaded
  486. DPagePtr    Word    ; address of its direct page space
  487. DPageSize    Word    ; size of direct page/stack segment
  488. DIBPtr    Long    ; pointer to the DIB for installing GS/OS drivers
  489. Filetype    Word    ; filetype of what we're after
  490. Auxtype    Word    ; auxtype of what we're after
  491.         ; (see IRData for explanation of word vs. long)
  492. Temp    Long    ; temporary storage and deref
  493. TempAlso    Long    ; more of the same
  494.  
  495. SizeLocals    EndLocals
  496.  
  497. ;
  498. ; Registers we save    and the RTL address
  499. ;
  500.  
  501. OldDBR    Byte
  502. OldDP    Word
  503. RTLAddr    Block 3
  504.  
  505.     BegParms
  506.  
  507. ;
  508. ; Parameters to the    request procedure
  509. ;
  510.  
  511. DataOut    Long
  512. DataIn    Long
  513. RequestCode    Word
  514.  
  515. SizeParms    EndParms    
  516.  
  517. ;
  518. ; The result from the routine
  519. ;
  520.  
  521. Result    Word
  522.  
  523. SizeEverything    EndLocals
  524.     
  525. ;
  526. ; Private equates to building (but not using) IR.  First, GS/OS and system
  527. ; equates.
  528. ;
  529.  
  530. InitID    equ $A000    ; setup file user ID
  531. DAID    equ $5000    ; DA user ID
  532. DriverID    equ $3900    ; driver user ID
  533. SupDrvrID    equ $3A00    ; supervisory driver ID
  534. INSTALL_DRIVER    equ $01FCA8    ; System Service call
  535. warm_cold_flag    equ $E101D0    ; bit 0 = 0 if cold startup
  536. BUSYFLAG    equ $E100FF    ; system busy flag (one byte)
  537. OS_KIND    equ $E100BC    ; currently active OS (one byte)
  538. OS_BUSY    equ $E100BE    ; word, bit 15 = 1 if GS/OS is busy
  539. KEYMODREG    equ $E0C025    ; keyboard modifiers register
  540.  
  541. ;
  542. ; Equates for IR's private queue mechanism
  543. ;
  544.  
  545. startIDCount    equ 20    ; number of user IDs in queues by default
  546. FinderExtQueue    equ 0
  547. NeedsHelloQueue    equ 1
  548. IRQueue    equ 2
  549. DelayedStartQueue    equ 3
  550. lockQueueHandle    equ $8000    ; add this to queue number to lock handle
  551.  
  552. sizeOfFTEntry    equ 8    ; eight bytes per entry in file type table
  553.  
  554. ;
  555. ; Equates for resource IDs in our resource fork
  556. ;
  557.  
  558. IR_Init_Icon    equ $1    ; rIcon
  559.  
  560. Preferences_Ctl_List equ $1003    ; rControlList
  561.  
  562. PSTR_00000001    equ $1    ; rPString
  563. PSTR_00000002    equ $2
  564. PSTR_00000003    equ $3
  565. PSTR_00000004    equ $4
  566. PSTR_00000005    equ $5
  567. PSTR_00000006    equ $6
  568. PSTR_00000007    equ $7
  569. PSTR_00000008    equ $8
  570. PSTR_00000009    equ $9
  571. PSTR_0000000A    equ $A
  572. PSTR_0000000B    equ $B
  573. PSTR_0000000C    equ $C
  574. PSTR_0000000D    equ $D
  575.  
  576. Preferences_LEText    equ $1    ; rTextForLETextBox2
  577. Permanently_LEText    equ $2
  578. If_duplicate_LEText    equ $3
  579. LETXTBOX_00000005    equ $5
  580. About_LEText    equ $6
  581.  
  582. Preferences_Window    equ $FFA    ; rWindParam1
  583.  
  584. irDuplicateWontDieAlert equ $1    ; rAlertString
  585. irAboutAlert    equ $2
  586. irNoFinderAlert    equ $3
  587. irBusyAlert    equ $4
  588.  
  589. IR_Version    equ $1    ; rVersion
  590.  
  591. Comment1    equ $1    ; rComment
  592. Comment2    equ $2
  593.  
  594. TitleID    equ $1    ; Control IDs
  595. OpenNewNDAID    equ $2
  596. FinderExtID    equ $3
  597. PermanentlyID    equ $4
  598. RadioPromptID    equ $5
  599. InstallNewID    equ $6
  600. TryKillOldID    equ $7
  601. AlwaysKillOldID    equ $8
  602. VersionID    equ $9
  603. AcceptID    equ $B
  604. CancelID    equ $C
  605. SaveID    equ $D
  606. CopyExistNDAsID    equ $E
  607. DoBeforeOpenID    equ $F
  608. DoAlertsID    equ $10
  609. UnderlineRectID    equ $11
  610. RadioRectID    equ $12
  611.  
  612. WindowRects    equ $1    ; rTwoRects
  613.  
  614.     EJECT
  615. *******************************************************************************
  616. *
  617. * Static and private data for IR
  618. *
  619. *******************************************************************************
  620.  
  621. IRData    RECORD    EXPORT
  622.  
  623. IRUserID    dc.w 0    ; IR's user ID
  624. IRBusyFlag    dc.w 0    ; non-zero if we're busy
  625. IRResFile    dc.w 0    ; reference number for our resource fork
  626.  
  627. ;
  628. ; This is the filetype table for filetypes we can feed to askIRToInstall.  We
  629. ; do this so we don't have to hard-code it in both askIRToInstall as well as
  630. ; finderSaysBeforeOpen and finderSaysOpenFailed.
  631. ;
  632. ; The table includes only word-value auxtypes, giving us a slight optimization
  633. ; by "knowing" that any auxtype with a non-zero high word is unacceptable.  See
  634. ; CheckFileAuxType.
  635. ;
  636. ; The four values are filetype, auxtype mask, auxtype and user ID.  Most of the auxtype
  637. ; masks and auxtypes are 0, so an AND #0, CMP #0 on an auxtype will always return
  638. ; TRUE.  Putting the User ID here really simplifies dispatching, but it does mean
  639. ; that we'll have to rework this if we ever need one file type to have two possible
  640. ; user ID ranges.
  641. ;
  642.  
  643. FTTableCount    dc.w (endFileTypeTable-fileTypeTable)/sizeOfFTEntry
  644.         ; that's a count, son
  645. FTTableSize    dc.w endFileTypeTable-fileTypeTable
  646. fileTypeTable    dc.w PermInitType,0,0,InitID
  647.     dc.w TempInitType,0,0,InitID
  648.     dc.w NDAType,0,0,DAID
  649.     dc.w CDAType,0,0,DAID
  650.     dc.w DriverType,DriverAuxMask,DriverAuxType,DriverID
  651.     dc.w GenLoadType,FindExtAuxMask,FindExtAuxType,InitID    ; for now
  652. endFileTypeTable
  653.  
  654. FinderString    str 'Apple~Finder~'
  655.     EXPORT IRString, ID1, ID2
  656. IRString    dc.b IRStringEnd-IRString-1
  657.     dc.b 'Apple~IR~'
  658. ID1    dc.b 'xx'
  659. ID2    dc.b 'xx~'
  660. IRStringEnd    equ *
  661. IRShortString    str 'Apple~IR~'
  662.  
  663.  
  664. ;
  665. ; Here's a copy of the finderSaysHello dataIn pointer
  666. ;
  667.  
  668. FSHdataIn    ds.l 1
  669.  
  670. ;
  671. ; This is the buffer for tellFinderAddToExtras
  672. ;
  673.  
  674. AddToXtras    dc.w 0    ; recvCount
  675. ATXresult    dc.w 0    ; result code
  676. ATXItemID    dc.w 0    ; item ID assigned by Finder
  677. ATXExtrasID    dc.w 0    ; extras menu ID
  678.  
  679. ;
  680. ; Here are the stored direct page and stack pointer for transferring to Inits and FEs
  681. ;
  682.  
  683. MyDP    ds.w 1
  684. MyStack    ds.w 1
  685.  
  686. ScreenRect    dc.w 0,0,200,640    ; for whooshing (in Finder only)
  687.  
  688. IRBootString    dc.b 'IR                    '
  689. IRBootVersion    dc.b '          '        ; ten spaces
  690.     dc.b 0
  691. VersionLength    dc.w 0
  692. IRVersion    dc.l 0    ; our version longword from our resource fork
  693.  
  694. ;
  695. ; Here's an extended task record for our DoModalWindow call
  696. ;
  697.  
  698. MyTaskRec
  699. EventWhat    ds.B 2
  700. EventMessage    ds.B 4
  701. EventWhen    ds.B 4
  702. EventWhere    ds.B 4
  703. EventModifiers    ds.B 2
  704. TaskData    ds.B 4
  705. TaskMask    dc.L $001FFFFF    ; that's everything we want
  706. LastClickTick    ds.B 4
  707. ClickCount    ds.B 2
  708. TaskData2    ds.B 4
  709. TaskData3    ds.B 4
  710. TaskData4    ds.B 4
  711. LastClickPtY    ds.B 2
  712. LastClickPtX    ds.B 2
  713.  
  714.  
  715. ;
  716. ; The preferences are stored as one word, defined as:
  717. ;  ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ 
  718. ; |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
  719. ; | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
  720. ; |____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|
  721. ;
  722. ;    |__________________________________|    |    |    |    |    |    |    |    |
  723. ;                      |                     |    |    |    |    |    |    |    |
  724. ;                   Reserved                 |    |    |    |    |    |    |    |
  725. ;                                            |    |    |    |    |    |    |    |
  726. ;   1 = don't alert user to problems --------+    |    |    |    |    |    |    |
  727. ;   1 = Wait for openFailed to do Finder stuff ---+    |    |    |    |    |    |
  728. ;   1 = Open this NDA if possible ---------------------+    |    |    |    |    |
  729. ;   1 = kill this Finder Extension on quitting -------------+    |    |    |    |
  730. ;   1 = don't futz with Apple Menu to install NDAs --------------+    |    |    |
  731. ;   1 = return error if duplicate can't be killed --------------------+    |    |
  732. ;   1 = return error if duplicate exists ----------------------------------+    |
  733. ;       Reserved ---------------------------------------------------------------+
  734. ;
  735. ; Now, truthfully, I could take more than one word to store all this stuff, but
  736. ; I don't really have a good reason to -- if I put each one in a separate word, it
  737. ; would require one fewer AND instruction per preference check -- but this makes it
  738. ; easy for any caller to the IR request procedure to override any preference.  That's
  739. ; also cool.
  740. ;
  741. ; We keep three copies -- the disk preferences and the local preferences.  Each time we
  742. ; get the preferences passed, we put them in the local copy unless we're instructed
  743. ; to write them to disk.  The temporary preferences are in effect only through
  744. ; askIRToInstall and are kept on the stack frame, not here.
  745. ;
  746. DiskPrefs    dc.w 0
  747. LocalPrefs    dc.w 0
  748.  
  749. ;
  750. ; Parameter blocks for creating, opening, read/writing and closing the preferences file
  751. ;
  752.  
  753. CreateParms    dc.w 4    ; parameter count
  754. CreatePath    dc.l 0    ; pointer to filename
  755.     dc.w $83    ; no rename -- file name is hard-coded
  756.     dc.w IRPrefsType    ; filetype
  757.     dc.l IRPrefsAuxType    ; auxtype
  758.  
  759. RWParms    dc.w 4
  760. RWrefnum    dc.w 0    ; reference number
  761. buffer    dc.l DiskPrefs    ; buffer pointer
  762. reqCount    dc.l 2    ; request count
  763. transferCount    dc.l 0    ; transfer count
  764.  
  765. CloseParms    dc.w 1
  766. CloseRefNum    dc.w 0    ; reference number
  767.  
  768. OpenParms    dc.w 3
  769. OpenRefNum    dc.w 0    ; reference number
  770. OpenPath    dc.l 0    ; pointer to filename
  771. OpenAccess    dc.w 0    ; requested access
  772.  
  773. PrefsPathPtr    dc.l 0    ; pointer to our prefs pathname
  774. PrefsFileName    str ':IR.Preferences'
  775.  
  776. DInfoParms    dc.w 4    ; pCount
  777. DInfoDevNum    dc.w 1    ; device #1
  778. DInfoDevName    dc.l NoName    ; don't want a name
  779. DInfoCharacteristics dc.w 0    ; characteristics
  780. DInfoBlocks    dc.l 4    ; block count
  781.  
  782. NotifyProcParms    dc.w 1    ; pCount
  783.     IMPORT IRNotifyProc
  784. NotifyProcPtr    dc.l IRNotifyProc
  785.  
  786. NoName    dc.l 0    ; zero buffer length
  787.  
  788. UserPathParms    dc.w 3    ; pCount
  789.     dc.w AppleShareFSID ; file system ID
  790.     dc.w 8    ; command == GetUserPath
  791. UserPathPtr    dc.l 0    ; pointer to user path
  792.  
  793. GFIParms    dc.w 8    ; enough to get the option list
  794. GFIPathPtr    dc.l 0    ; pathname pointer
  795.     dc.w 0    ; access
  796. GFIFileType    dc.w 0    ; filetype
  797. GFIAuxType    dc.l 0    ; auxtype
  798.     dc.w 0    ; storage type
  799.     ds.b 16    ; 16 bytes for dates/times
  800.     dc.l GFIOptionList    ; option list pointer
  801.  
  802. GFIOptionList    dc.w $2E
  803. OptionListReqSize    dc.w 0    ; output size
  804. OptionListFSID    dc.w 0    ; file system ID
  805.     ds.b $30    ; storage space for stuff we don't read
  806.  
  807. srqOutBuffer    dc.w 0    ; recvCount
  808. srqResultID    dc.w 0    ; resulting user ID
  809. srqFlags    dc.w 0    ; flags
  810.  
  811. ;
  812. ; This is the table of handles for the queues we have.  We identify queues with
  813. ; a zero-based count -- zero refers to the first pointer, 1 refers to the second,
  814. ; etc.  Call AddIDToQueue to add a user ID to one of these, but just dereference
  815. ; and use them when necessary.
  816. ;
  817.  
  818. QueueTable
  819.  
  820. FETable    dc.l 0    ; Finder Extensions to kill
  821. FSHTable    dc.l 0     ; Code that needs finderSaysHello calls
  822. IRTable    dc.l 0    ; list of IRs that need to be killed
  823. DelayedStartTable    dc.l 0    ; list of things that need to be done at Idle
  824.  
  825.  
  826. ;
  827. ; This is the global flag that tells IRGetsToWork that it's being called from
  828. ; finderSaysIdle; that means it's OK to actually really truly install things
  829. ; because it's OK to send finderSaysGoodbye to duplicates that may exist.
  830.  
  831. IdleGlobalFlag    dc.w 0
  832.  
  833. ;
  834. ; Here's the menu item template for the Extras menu item.
  835. ;
  836.  
  837. PrefsItem    dc.w $8000    ; set bit fifteen to say add dividing line above
  838. PrefsID    dc.w 0    ; Finder tells us this
  839.     dc.w 0    ; FEs shouldn't have hard-coded key equivalents
  840.     dc.w 0    ; no check item
  841.     dc.w 0     ; ref by pointer, no styles
  842.     dc.l PrefsItemName    ; preferences item name
  843.     
  844. PrefsItemName    str 'IR Preferences…'
  845.     
  846.     EndR
  847.     
  848.     EJECT
  849. *******************************************************************************
  850. *
  851. IRRequestProc    PROCNAME    EXPORT
  852. *
  853. * Description:    This is the request    procedure passed to    AcceptRequests
  854. *    by IR.  It handles all the requests we accept, both
  855. *    from the Finder and    from IR itself.
  856. *
  857. * The Finder will send us all the Finder requests, which we    accept and respond
  858. * to as you might expect.  For example,    we accept finderSaysHello and respond
  859. * with tellFinderAddToExtras for our preferences dialog, etc.
  860. *
  861. * However, we also accept a special request to "IR" any of the kinds of
  862. * documents IR accepts (DAs, Inits, GS/OS drivers and Finder extensions at
  863. * this writing).  When we determine we need to do something    with an IR-able
  864. * file, we just call SendRequest to ask    ourself to do it.
  865. *
  866. * It sounds weird, but it allows us to put all the work into this procedure and
  867. * let the IR application (or other people) call us.  All we    have to do is take
  868. * a little care to be re-entrant and it    all works just fine.
  869. *
  870. * We do our private    setup before dispatching just for general health.
  871. *
  872. * By the way, if most of this routine looks kind of familiar, don't strain
  873. * yourself trying to figure out why.  The stack setup and teardown is lifted
  874. * almost verbatim from the DTS Sample Code tool FakeModalDialog, and the table
  875. * dispatch for the requests we accept comes from the assembly shell's event-
  876. * dispatching routine.  If code works, there's no need to rewrite it.
  877. *
  878. * Inputs:    reqCode (word) -- the request code
  879. *    dataIn (long)  -- pointer to input data
  880. *    dataOut (long) -- pointer to output data
  881. *
  882. * Outputs:    Besides filling in dataOut:
  883. *    result (word)  -- set bit 15 if we accept the request
  884. *
  885. * External Refs:    
  886.     IMPORT IRGreetsFinder
  887.     IMPORT IRBidsFinderFarewell
  888.     IMPORT IRGetsAnOpen
  889.     IMPORT IRLooksAtExtras
  890.     IMPORT IRGoesAway
  891.     IMPORT IRStartsUp
  892.     IMPORT IRSaysIRHere
  893.     IMPORT IRGetsToWork
  894.     IMPORT IRReturnsPreferences
  895.     IMPORT IRSetsPreferences
  896.     IMPORT IRDoesPreferences
  897.     IMPORT IRSeesIdle
  898.     IMPORT KillQueueEntries
  899.     WITH IRData
  900. *                   
  901. * Entry Points:    None.
  902. *
  903. *******************************************************************************
  904.  
  905. ;
  906. ; Since we use a fair amount of stack space, don't accept any requests
  907. ; if the stack is in page one.  Dave says <result is pre-zeroed for us,
  908. ; so if the stack is in page one just strip the input parameters and
  909. ; get out of here.
  910. ;
  911.  
  912.     tsc
  913.     and #$FF00
  914.     xba    ; stack page now in low byte of A
  915.     dec a
  916.     beq StripInputParms    ; skip everything if we were in page one stack
  917.  
  918.     phb    ; save the data bank register
  919.     phk
  920.     plb    ; set the DBR to our code bank
  921.     phd    ; save direct page register.
  922.     tsc    ; make space for locals.
  923.     sec
  924.     sbc #sizeLocals
  925.     tcs
  926.     tcd    ; Set direct page register.
  927.  
  928.     stz <result    ; this isn't defined on entry
  929.     stz <OldResourceApp ; so we can keep it straight
  930.     
  931.     lda IRTable
  932.     ora IRTable+2
  933.     beq @DoTheRequest    ; kill this queue if a pointer exists
  934.     lda #0    ; no finderSaysGoodbye
  935.     ldx #IRQueue
  936.     jsr KillQueueEntries
  937.     
  938. @DoTheRequest    lda <RequestCode
  939.     ldx #endRequestTable-RequestTable-4
  940. checkNextCode    cmp RequestTable,x    ; are we handling this request?
  941.     beq doRoutine    ; yes, then call a routine
  942.     dex    ; no, then keep checking
  943.     dex
  944.     dex
  945.     dex
  946.     bpl checkNextCode    ; keep scanning table
  947.  
  948.     bra notAccepted    ; not a request we take, so politely refuse                 
  949.  
  950. doRoutine    lda #$8000    ; we're going to accept this request
  951.     sta <result
  952.     
  953.     jsr (RequestTable+2,x) ; call the routine
  954.  
  955. ;
  956. ; We assume that the request procedure has filled in all the buffers and left
  957. ; any error code in    A.  Since not all routines store result codes, we only
  958. ; put something in [<dataOut],2 if the carry flag is set.  That applies to
  959. ; zero (no error) results as well.
  960. ;
  961.  
  962.     bcc noStoreError    ; skips storing the error
  963.     ldy #2
  964.     sta [<dataOut],y    ; save error code.
  965.  
  966. noStoreError    lda <OldResourceApp    ; did we change this?
  967.     beq noResAppChange    ; as if we never did anything
  968.     
  969.     pha
  970.     _SetCurResourceApp
  971.     
  972. noResAppChange        ; same place as
  973. notAccepted    tdc    ; get rid of local variables.
  974.     clc
  975.     adc #sizeLocals
  976.     tcs
  977.     pld    ; restore direct page register
  978.     plb    ; restore data bank    register
  979.  
  980. stripInputParms    lda 1,s    ; move return address.
  981.     sta 1+sizeParms,s
  982.     lda 2,s
  983.     sta 2+sizeParms,s
  984.  
  985.     tsc    ; pull passed parms    off stack.
  986.     clc    ; carry is already cleared if stack
  987.     adc #sizeParms    ; isn't in page one.
  988.     tcs
  989.  
  990.     rtl
  991.  
  992.  
  993. ;
  994. ; Since the dispatch code searches the entire table, we can    add or subtract
  995. ; lines as necessary to add or delete requests we accept.  This is Handy.
  996. ;
  997.  
  998. RequestTable
  999.     dc.w finderSaysHello, IRGreetsFinder        ; *
  1000.     dc.w finderSaysGoodbye, IRBidsFinderFarewell    ; *
  1001.     dc.w finderSaysBeforeOpen, IRGetsAnOpen        ; *
  1002.     dc.w finderSaysOpenFailed, IRGetsAnOpen        ; *
  1003.     dc.w finderSaysIdle, IRSeesIdle
  1004.     dc.w finderSaysExtrasChosen,IRLooksAtExtras    ; *
  1005.     dc.w srqGoAway,    IRGoesAway        ; *
  1006.     dc.w askIRStartUp,  IRStartsUp        ; *
  1007.     dc.w askIRAreYouThere, IRSaysIRHere        ; *
  1008.     dc.w askIRToInstall,IRGetsToWork        ; *
  1009.     dc.w askIRGetPrefs,    IRReturnsPreferences    ; *
  1010.     dc.w askIRSetPrefs,    IRSetsPreferences        ; *
  1011.     dc.w askIRDoPrefs,  IRDoesPreferences        ; *
  1012.  
  1013. endRequestTable
  1014.  
  1015.     EndP
  1016.  
  1017.     EJECT
  1018. *******************************************************************************
  1019. *
  1020. IRGreetsFinder    PROCNAME
  1021. *
  1022. * Description:    Our response to finderSaysHello, we add our menu item to
  1023. *    the Extras menu.
  1024. *
  1025. *
  1026. * Inputs:    None
  1027. *
  1028. * Outputs:    None
  1029. *
  1030. * External Refs:
  1031.  
  1032.     import IRData
  1033.     with IRData
  1034. *
  1035. * Entry Points:
  1036. *
  1037. *******************************************************************************
  1038.  
  1039.     lda <dataIn
  1040.     sta FSHdatain
  1041.     lda <dataIn+2
  1042.     sta FSHdatain+2    ; copy this for our use
  1043.     
  1044.     pushword #tellFinderAddToExtras
  1045.     pushword #sendToName+stopAfterOne
  1046.     pushlong #FinderString
  1047.     pushlong #PrefsItem
  1048.     pushlong #AddToXtras
  1049.     _SendRequest
  1050.  
  1051.     clc
  1052.     rts
  1053.     
  1054.     EndP
  1055.  
  1056.  
  1057.     EJECT
  1058. *******************************************************************************
  1059. *
  1060. IRBidsFinderFarewell PROCNAME
  1061. *
  1062. * Description:    Our response to finderSaysGoodbye; we kill any Finder
  1063. *    extensions we have to kill and go away.
  1064. *
  1065. *
  1066. * Inputs:    None
  1067. *
  1068. * Outputs:    None
  1069. *
  1070. * External Refs:
  1071.     with IRData
  1072.     import KillQueueEntries
  1073. *
  1074. * Entry Points:
  1075. *
  1076. *******************************************************************************
  1077.  
  1078. ;
  1079. ; Do nothing if we're not actively in the Finder!
  1080. ;
  1081.  
  1082.     lda FSHDataIn
  1083.     ora FSHDataIn+2
  1084.     bne @KillFEQueue
  1085.     stz <result    ; deny this request
  1086.     bra @OverAndOut
  1087.  
  1088. @KillFEQueue    lda #0
  1089.     ldx #FinderExtQueue
  1090.     jsr KillQueueEntries ; they've all gotten finderSaysGoodbye
  1091.     
  1092.     pushword #tellFinderRemoveFromExtras
  1093.     pushword #sendToName+stopAfterOne
  1094.     pushlong #FinderString
  1095.     pea 0
  1096.     pushword ATXItemID
  1097.     pushlong #AddToXtras ; same buffer will do
  1098.     _SendRequest
  1099.     
  1100.     stz FSHDataIn
  1101.     stz FSHDataIn+2
  1102.     
  1103. @OverAndOut    clc
  1104.     rts    ; that's all we gotta do.
  1105.         ; (ain't subroutines neat?)
  1106.     EndP
  1107.     
  1108.     EJECT
  1109. *******************************************************************************
  1110. *
  1111. IRGetsAnOpen    PROCNAME
  1112. *
  1113. * Description:    This is the brunt of the Finder work; we come here on
  1114. *    BeforeOpen and OpenFailed and do the real work here if
  1115. *    it's appropriate.
  1116. *
  1117. *
  1118. * Inputs:    dataIn as passed by Finder
  1119. *
  1120. * Outputs:    None
  1121. *
  1122. * External Refs:
  1123.     with IRData
  1124.     import CheckFileAuxType
  1125.     IMPORT AddIDToQueue
  1126. *
  1127. * Entry Points:
  1128. *
  1129. * Notes:
  1130. *
  1131. * 2.0a4 -- MD
  1132. * I leave the errors in the accumulator so you can see which errors I would
  1133. * return and why, but GotOpenOut now properly _clears_ the carry flag so the
  1134. * RequestProc doesn't store the result code in the second word of the dataOut
  1135. * buffer, since it is (after all) reserved.
  1136. *
  1137. *******************************************************************************
  1138.  
  1139. ;
  1140. ; This routine is not re-entrant, so we check to make sure we're not busy
  1141. ; doing something else first.
  1142. ;
  1143.  
  1144.     lda irBusyFlag
  1145.     bne @Busy
  1146.     
  1147.     inc irBusyFlag
  1148.     bra @CheckType
  1149.     
  1150. @Busy    stz <result    ; denying the request
  1151.     lda #irBusy
  1152.     brl GotOpenOut1
  1153.  
  1154. ;
  1155. ; Even though IRGetsToWork does type checking, we need to do the same thing so
  1156. ; we can know if we need to "zoom" out or not before getting anything done.
  1157. ; But first, we see if this is the request we're supposed to be acting on
  1158. ; and pass if it's not.
  1159. ;
  1160.  
  1161. ; This is kind of skanky but more efficient than other ways...
  1162.  
  1163. @CheckType    ldy #16
  1164.     lda [<dataIn],y    ; the modifiers
  1165.     and #controlKey    ; non-zero if control was down
  1166.     pha    ; store on stack
  1167.     
  1168.     lda LocalPrefs
  1169.     and #irWaitOpenFailed
  1170.     lsr a
  1171.     lsr a
  1172.     xba
  1173. ;
  1174. ; This is an efficient way to do this but it depends on illicit knowledge
  1175. ; that irWaitOpenFailed is the sixth bit of the preferences word.
  1176. ;
  1177.  
  1178.     eor 1,s
  1179.     and #controlKey
  1180.     sta 1,s
  1181.     
  1182. ;
  1183. ; After that little trick, 1,s contains $0000 if and only if both the Control
  1184. ; key was down _and_ the irWaitOpenFailed bit was set, or if neither was.
  1185. ; Those circumstances are when we accept the request if it's
  1186. ; finderSaysBeforeOpen, and when we reject the request if it's
  1187. ; finderSaysOpenFailed.
  1188. ;
  1189.     
  1190.     lda <requestCode
  1191.     cmp #finderSaysBeforeOpen
  1192.     bne @ItsOpenFailed
  1193.     
  1194. @ItsBeforeOpen    pla
  1195.     beq @DoItNow
  1196.     stz <result    ; denying the request
  1197.     brl GotOpenOut
  1198.     
  1199. @ItsOpenFailed    pla
  1200.     bne @DoItNow
  1201.     stz <result    ; denying the request
  1202.     brl GotOpenOut
  1203.  
  1204.     
  1205. @DoItNow    ldy #10
  1206.     lda [<dataIn],y    ; filetype
  1207.     pha
  1208.     iny
  1209.     iny
  1210.     lda [<dataIn],y    ; auxtype low word
  1211.     pha
  1212.     iny
  1213.     iny
  1214.     lda [<dataIn],y    ; auxtype high word
  1215.     tay
  1216.     plx
  1217.     pla
  1218.     jsr CheckFileAuxType
  1219.     bcc @CheckPrinting
  1220.  
  1221.     stz <result    ; denying the request
  1222.     lda #irNotIRFile    ; tell the caller we can't do it
  1223.     brl GotOpenOut
  1224.  
  1225. ;
  1226. ; Look to see if the document was "opened" or "Printed" -- it doesn't make sense
  1227. ; for IR to accept "Print" requests.
  1228. ;
  1229.  
  1230. @CheckPrinting    ldy #22    ; offset to open/print flag in parameters
  1231.     lda [<dataIn],y
  1232.     beq @KeepGoing
  1233.     stz <result    ; denying the request
  1234.     lda #irCantPrint
  1235.     brl GotOpenOut
  1236.  
  1237. ;
  1238. ; OK, we're going to do it.  Zoom out and call IR's request proc to do the work.
  1239. ;
  1240.  
  1241. @KeepGoing    pushlong #$80000000
  1242.     pushlong [<dataIn],6 ; a nifty feature I rarely use
  1243.     pushlong #ScreenRect
  1244.     _WhooshRect
  1245.     
  1246.     lda LocalPrefs
  1247.     sta OurFlags
  1248.     ldy #2
  1249.     lda [<dataIn],y
  1250.     sta OurFilePtr
  1251.     iny
  1252.     iny
  1253.     lda [<dataIn],y
  1254.     sta OurFilePtr+2
  1255.     ldy #10
  1256.     lda [<dataIn],y
  1257.     sta OurFileType
  1258.     iny
  1259.     iny
  1260.     lda [<dataIn],y
  1261.     sta OurAuxType
  1262.     iny
  1263.     iny
  1264.     lda [<dataIn],y
  1265.     sta OurAuxType+2
  1266.     
  1267.     pushword #askIRToInstall
  1268.     pushword #sendToName+stopAfterOne
  1269.     pushlong #IRString 
  1270.     pushlong #OurDataIn
  1271.     pushlong #OurDataOut
  1272.     _SendRequest
  1273.     
  1274. ;
  1275. ; 2.0a4 -- check to see if the request was accepted before adding it to the
  1276. ; NeedsHello queue.
  1277. ;
  1278.  
  1279.     lda OurIRError
  1280.     bne @SkipHelloQueue
  1281.     
  1282. ;
  1283. ; Since we're in the Finder, and the Finder can't respond to most requests during
  1284. ; BeforeOpen or OpenFailed, we queue the user ID in the NeedsHello queue so we
  1285. ; can send finderSaysHello during the next finderSaysIdle message.
  1286. ;
  1287.  
  1288. @AddToHelloQueue    lda OurUserID
  1289.     ldx #NeedsHelloQueue
  1290.     jsr AddIDToQueue
  1291.     
  1292. ;
  1293. ; That's all this guy needs to do, except zoom out and return any result code
  1294. ; 2.0a3 -- everyone but me thinks whooshing back in on NDAs is weird, so now
  1295. ; we don't any more.
  1296. ;
  1297.  
  1298. @SkipHelloQueue    lda OurFileType
  1299.     cmp #NDAType
  1300.     beq GotOpenOut
  1301.  
  1302. @DoWhooshIn    pushlong #$00000000
  1303.     pushlong [<dataIn],6 ; a nifty feature I rarely use
  1304.     pushlong #ScreenRect
  1305.     _WhooshRect
  1306.  
  1307. GotOpenOut    dec irBusyFlag    
  1308. GotOpenOut1    clc    ; we branch here if we were busy
  1309.     rts
  1310.  
  1311. OurDataIn
  1312. OurFlags    dc.w 0    ; flags
  1313. OurFilePtr    dc.l 0    ; file name pointer
  1314. OurFileType    dc.w 0    ; file type
  1315. OurAuxType    dc.l 0    ; auxtype
  1316.  
  1317. OurDataOut
  1318. OurRecvCount    dc.w 0
  1319. OurIRError    dc.w 0
  1320. OurUserID    dc.w 0
  1321.  
  1322.     EndP
  1323.     
  1324.     EJECT
  1325. *******************************************************************************
  1326. *
  1327. IRLooksAtExtras    PROCNAME
  1328. *
  1329. * Description:    Our answer to finderSaysExtrasChosen, we see if it's the
  1330. *    IR preferences dialog and if so, send the request to
  1331. *    askIRDoPrefs.  Fortunately, that takes no parameters so
  1332. *    we don't have to worry about reentrancy.
  1333. *
  1334. *
  1335. * Inputs:    from Finder.
  1336. *
  1337. * Outputs:    None
  1338. *
  1339. * External Refs:
  1340.     with IRData
  1341. *
  1342. * Entry Points:
  1343. *
  1344. *******************************************************************************
  1345.  
  1346.     lda <dataIn
  1347.     cmp ATXItemID
  1348.     beq @ItsOurID
  1349.     
  1350.     stz <result    ; we're not taking the request after all
  1351.     bra @NotOurID
  1352.     
  1353. @ItsOurID    pushword #askIRDoPrefs
  1354.     pushword #sendToName+stopAfterOne
  1355.     pushlong #IRString
  1356.     lda #0
  1357.     pha
  1358.     pha    ; no dataIn
  1359.     pha
  1360.     pha    ; no dataOut
  1361.     _SendRequest
  1362.     
  1363. @NotOurID    clc
  1364.     rts
  1365.     
  1366.     EndP
  1367.     
  1368.     EJECT
  1369. *******************************************************************************
  1370. *
  1371. IRStartsUp    PROCNAME
  1372. *
  1373. * Description:    This request code starts up IR.  Provided so the request
  1374. *    procedure can be completely separate of all the other parts
  1375. *    of the IR package that call it.  Starts things and displays
  1376. *    the boot info with ShowBootInfo.
  1377. *
  1378. *
  1379. * Inputs:    dataIn is a pointer to the following:
  1380. *    word:  user ID
  1381. *    
  1382. *
  1383. * Outputs:    None.
  1384. *
  1385. * External Refs:    
  1386.     WITH IRData
  1387.     IMPORT GetPrefsFromDisk
  1388.     IMPORT AddIDToQueue
  1389.     IMPORT GiveMeMyFork
  1390.     IMPORT IRNotifyProc
  1391. *
  1392. * Entry Points:    None.
  1393. *
  1394. *******************************************************************************
  1395.  
  1396.     stz IRUserID    ; for safety
  1397.  
  1398. ;
  1399. ; See if another IR is present.  Since we won't accept the request
  1400. ; until our user ID is non-zero, we can call askIRAreYouThere until we
  1401. ; get an error, adding the resulting user ID to the IRQueue each time.
  1402. ;
  1403.  
  1404. @FindIRLoop    pea askIRAreYouThere
  1405.     pea sendToName+stopAfterOne
  1406.     pushlong #IRShortString
  1407.     lda #0
  1408.     pha
  1409.     pha    ; dataIn == NIL
  1410.     pushlong #OurBuffer
  1411.     _SendRequest
  1412.     php    ; save this in case I forget to later
  1413.     
  1414.     lda [<dataIn]    ; the user ID
  1415.     sta IRUserID    ; keep it for a while
  1416.     
  1417.     plp
  1418.     bcs @NoMoreIRs
  1419.     lda TargetID
  1420.     ldx #IRQueue
  1421.     jsr AddIDToQueue
  1422.     
  1423. ;
  1424. ; Display the boot info
  1425. ;
  1426.     
  1427. @NoMoreIRs    jsr GiveMeMyFork
  1428.  
  1429.     pha
  1430.     pha    ; space for result
  1431.     pushword #rVersion
  1432.     pushlong #IR_Version
  1433.     _LoadResource
  1434.     pulllong <Temp
  1435.     lda [<Temp]
  1436.     tax
  1437.     ldy #2
  1438.     lda [<Temp],y
  1439.     sta <Temp+2
  1440.     stx <Temp    ; temp points to version resource
  1441.     
  1442.     lda #0
  1443.     pha    ; flags
  1444.     lda [<temp],y    ; high word of version number (Y still = 2)
  1445.     pha
  1446.     sta IRVersion+2
  1447.     lda [<temp]
  1448.     pha
  1449.     sta IRVersion
  1450.     pushlong #IRBootVersion
  1451.     _VersionString
  1452.     
  1453.     pushword #$FFFF    ; release now
  1454.     pushword #rVersion
  1455.     pushlong #IR_Version
  1456.     _ReleaseResource    ; we're done with this for good
  1457.     
  1458.     lda IRBootVersion    ; first word of buffer
  1459.     and #$00FF    ; make it a word
  1460.     sta VersionLength    ; for later use
  1461.     
  1462.     lda IRBootVersion
  1463.     and #$FF00    ; clear low byte (first character)
  1464.     ora #'v'    ; put 'v' in first character
  1465.     sta IRBootVersion    ; now the string for ShowBootInfo is right
  1466.     
  1467.     pha
  1468.     pha    ; space for result
  1469.     pushword #rIcon
  1470.     pushlong #IR_Init_Icon
  1471.     _LoadResource
  1472.     pulllong <Temp
  1473.     lda [<Temp]
  1474.     tax
  1475.     ldy #2
  1476.     lda [<Temp],y
  1477.     sta <Temp+2
  1478.     stx <Temp    ; Temp points to icon in memory
  1479.         
  1480.     pushlong #IRBootString
  1481.     pei <Temp+2
  1482.     pei <Temp    ; pointer to icon
  1483.     _ShowBootInfo
  1484.     
  1485.     pushword #2    ; purge level 2
  1486.     pushword #rIcon
  1487.     pushlong #IR_Init_Icon
  1488.     _ReleaseResource    ; we're done with this for now
  1489.     
  1490.     jsr GetPrefsFromDisk ; stuff to find prefs path and read it
  1491.     
  1492.     _AddNotifyProcGS NotifyProcParms    
  1493.  
  1494.     rts
  1495.     
  1496. OurBuffer    dc.w 0    ; recvCount
  1497. TargetID    dc.w 0    ; ID of any IRs around
  1498. OurVersion    dc.w 0    ; Version for any IR already installed
  1499.  
  1500.     EndP
  1501.  
  1502.  
  1503.     EJECT
  1504. *******************************************************************************
  1505. *
  1506. IRSaysIRHere    PROCNAME
  1507. *
  1508. * Description:    Simple procedures -- we just accept it to say we're here.
  1509. *    If we're in the middle of starting up, we do _not_ accept
  1510. *    this request.
  1511. *
  1512. *
  1513. * Inputs:    None.  dataIn is ignored.
  1514. *
  1515. * Outputs:    dataOut points to a buffer:
  1516. *    +000 recvCount
  1517. *    +002 IR user ID
  1518. *    +004 IR's version longword
  1519. *
  1520. * External Refs:    None.
  1521. *
  1522. * Entry Points:    
  1523.     WITH IRData
  1524. *
  1525. *******************************************************************************
  1526.  
  1527.     lda IRUserID
  1528.     bne @Accept
  1529.     stz <result    ; denying the request
  1530.     clc
  1531.     bra @rts    ; so I can't stand multiple exit paths
  1532.     
  1533. @Accept    ldy #4
  1534.     lda IRVersion
  1535.     sta [<dataOut],y
  1536.     iny
  1537.     iny
  1538.     lda IRVersion+2
  1539.     sta [<dataOut],y    ; put our version in the output buffer.
  1540.     
  1541.     lda IRUserID    ; again
  1542.     sec    ; carry set makes the main request proc
  1543. @rts    rts    ; return A at +002 in dataOut
  1544.  
  1545.     EndP
  1546.  
  1547.     EJECT
  1548. *******************************************************************************
  1549. *
  1550. IRGetsToWork    PROCNAME
  1551. *
  1552. * Description:    Here it is, finally, the meat and potatoes of IR.  This is
  1553. *    the request procedure that does what it    is that IR does --
  1554. *    install things after boot.
  1555. *
  1556. *
  1557. * Inputs:    dataIn to the request proc is formatted as follows:
  1558. *
  1559. *    word:  flags (defined in E16.IR)
  1560. *    long:  pointer to class one pathname of    file to install
  1561. *    word:  filetype
  1562. *    long:  auxtype
  1563. *
  1564. * Outputs:    dataOut is a pointer formatted as follows:
  1565. *
  1566. *    word:  recvCount (number of acceptors)
  1567. *    word:  irError (any error code)
  1568. *    word:  user ID assigned to installed file
  1569. *
  1570. * External Refs:
  1571.     with IRData
  1572.     import CheckFileAuxType
  1573.     import DoDrivers
  1574.     import DoInitsFEs
  1575.     import DoCDAs
  1576.     import DoNDAs
  1577.     import OpenNDAByUserID
  1578.     import UserIDToDAID
  1579.     import DoAlertWindow
  1580.     import AddIDToQueue
  1581. *
  1582. * Entry Points:
  1583. *
  1584. *******************************************************************************
  1585.  
  1586. KillWithoutMercy    equ Temp+2    ; temporary flag for power users
  1587.  
  1588.     stz <ThisInitID
  1589.     stz <MyDPageFlag    ; note that we did not allocate memory
  1590.     stz <KillWithoutMercy
  1591.     
  1592.  
  1593. ; First, check the environment and see if we can do our thing.
  1594.  
  1595.     lda >OS_KIND
  1596.     and #$00FF    ; only low byte significant
  1597.     cmp #$0001    ; OS_KIND == 1 -> GS/OS is active
  1598.     bne @IRCantDoIt
  1599. @GSOSHere    lda >OS_BUSY
  1600.     bpl @WeCanGoOn
  1601. @IRCantDoIt    lda #irGSOSNotAvail
  1602.     brl ErrorOut
  1603.     
  1604. ; Next, set the local prefs depending on the flag word
  1605.  
  1606. @WeCanGoOn    lda [<dataIn]    ; get the flags
  1607.     sta <TempPrefs
  1608.     ror a    ; put bit zero in the carry
  1609.     bcs @GotPrefs
  1610.     lda LocalPrefs
  1611.     sta <TempPrefs    ; if not bit zero, use regular preferences
  1612.     
  1613.  
  1614. ;*** See if the file is one that we can install, and set up our direct page parameters
  1615.  
  1616. @GotPrefs    lda #1
  1617.     trb <TempPrefs    ; clear bit zero
  1618.     
  1619.     ldy #2
  1620.     lda [<dataIn],y
  1621.     sta <FilePointer
  1622.     iny
  1623.     iny
  1624.     lda [<dataIn],y
  1625.     sta <FilePointer+2
  1626.     iny
  1627.     iny
  1628.     lda [<dataIn],y    ; filetype
  1629.     sta <FileType
  1630.     iny
  1631.     iny
  1632.     lda [<dataIn],y    ; auxtype low word
  1633.     sta <auxtype
  1634.     iny
  1635.     iny
  1636.     lda [<dataIn],y    ; auxtype high word
  1637.     sta <auxtype+2
  1638.  
  1639.     tay    ; high word in Y
  1640.     ldx <auxtype
  1641.     lda <FileType    ; filetype in A
  1642.     jsr CheckFileAuxType
  1643.     bcc @ItsAnIRFile
  1644.  
  1645.     lda #irNotIRFile
  1646.     brl ErrorOut
  1647.     
  1648. ;
  1649. ; Search to see if the Loader knows about the file and do what the flags say.
  1650. ; First, we look to see if any duplicates exist by calling GetUserID2.
  1651. ;
  1652.  
  1653.  
  1654. @ItsAnIRFile    sta <ThisInitID    ; range at first
  1655.     
  1656. @TryDuplicate    pha
  1657.     pei <FilePointer+2
  1658.     pei <FilePointer
  1659.     _GetUserID2
  1660.     plx    ; the existing user ID
  1661.     stx <Temp    ; hold it for a minute
  1662.     bcc @CheckForNDA
  1663.     brl @MustInitialLoad ; not found, have to get it from disk
  1664.     
  1665. ;
  1666. ; Check to see here if this is an existing NDA we should just open.
  1667. ;
  1668.  
  1669. @CheckForNDA    lda <Filetype
  1670.     cmp #NDAType
  1671.     bne @NotNDA    ; if equal, it's an existing NDA
  1672.     
  1673.     lda <TempPrefs
  1674.     and #irCopyExistNDAs
  1675.     bne @NotNDA    ; skip if the flag isn't set
  1676.  
  1677.     pha    ; space for result
  1678.     _DeskStatus
  1679.     pla
  1680.     beq @NotNDA    ; skip if Desk Manager not started
  1681.     
  1682.     lda <Temp    ; the user ID
  1683.     jsr OpenNDAByUserID
  1684.     brl @CleanUp    ; get out of here
  1685.     
  1686. ;
  1687. ; Here's where the irKillDuplicates flag comes into play.  If the flag is set, we refuse
  1688. ; to go anywhere unless the thing accepts the srqGoAway code.  If the flag is clear,
  1689. ; we'll install a duplicate if srqGoAway is not accepted.  (We can't just _Restart, since
  1690. ; Restart for an installed file just returns the existing entry point -- jumping to the
  1691. ; entry point of GSBug even when it's running is not a winning proposition, for example.
  1692. ;
  1693. ; 2.0a4 -- if we're going to remove a DA, we also must remove it from the
  1694. ; Desk Manager's lists.
  1695. ;
  1696.  
  1697. @NotNDA    cmp #DriverType
  1698.     bne @ReadyToRemove
  1699.     lda #irDuplicateWontDie 
  1700.     sta <Temp    ; used as an error code later on
  1701.     stz <ThisInitID    ; no user ID here
  1702.     brl @CleanUp    ; GS/OS drivers can never be removed, and
  1703.         ; the OS will reject duplicate ones so I
  1704.         ; don't bother asking it to.
  1705.     
  1706. ;
  1707. ; Sit down -- this gets complicated.
  1708. ;
  1709. ; <deep breath>
  1710. ;
  1711. ; OK.  If we're in the Finder, we can't just kill duplicates.  We'd have
  1712. ; to send them finderSaysGoodbye first, but we can't do that if we're
  1713. ; responding to finderSaysOpenFailed or finderSaysBeforeOpen.  So, if we
  1714. ; are in the Finder, we add the temporary preferences and the user ID of
  1715. ; the duplicate to a "Delayed Start" queue -- we'll install everything in
  1716. ; that queue next time we hit finderSaysIdle.  So, we check to see if we
  1717. ; are in the Finder, and we check to see if it's safe to do our thing.
  1718. ; If so, proceed.  If not, add the preferences and the user ID to the
  1719. ; DelayedStartQueue and accept the request with the error "irDelayedStart."
  1720. ;
  1721. ; 2.0f1 -- we should skip all duplicate efforts if irNoDuplicates is clear.
  1722. ;
  1723.  
  1724. @ReadyToRemove    lda <TempPrefs
  1725.     and #irNoDuplicates
  1726.     bne @TestForFinder
  1727.     brl @MustInitialLoad
  1728.     
  1729. @TestForFinder    lda FSHDataIn
  1730.     ora FSHDataIn+2    ; are we really in Finder?
  1731.     beq @SendGoAway    ; no, so don't send finderSaysGoodbye
  1732.     
  1733. ; We're in the Finder, but is it safe?
  1734.  
  1735.     lda IdleGlobalFlag
  1736.     bne @SendGoodbye    ; if this is non-zero, it's OK to proceed.
  1737.     
  1738. ; Not safe -- add things to queue!
  1739.  
  1740.     lda <Temp    ; user ID
  1741.     ldx #DelayedStartQueue
  1742.     jsr AddIDToQueue    ; add first the user ID
  1743.     lda <TempPrefs
  1744.     ldx #DelayedStartQueue
  1745.     jsr AddIDToQueue    ; and then the preferences!
  1746.     
  1747.     lda #irDelayedStart 
  1748.     sta <Temp    ; used as an error code later on
  1749.     stz <ThisInitID    ; no user ID here
  1750.     brl @CleanUp    ; have to accept request but do nothing
  1751.     
  1752.     
  1753.     
  1754. @SendGoodbye    pea finderSaysGoodbye
  1755.     pea sendToUserID    ; don't stop after one in case they have
  1756.         ; multiple request procedures
  1757.     pea 0    ; high word of target
  1758.     pei <Temp    ; user ID
  1759.     lda #0
  1760.     pha
  1761.     pha    ; dataIn is nil
  1762.     pha
  1763.     pha    ; dataOut is nil
  1764.     _SendRequest    
  1765.     bcc @SendGoAway    
  1766.     brl @WontGoAway    ; don't try srqGoAway if can't say goodbye
  1767.     
  1768. @SendGoAway    pea srqGoAway    ; request code
  1769.     pea sendToUserID    ; how to send
  1770.     pea 0
  1771.     pei <Temp    ; the user ID to send to
  1772.     lda #0
  1773.     pha
  1774.     pha    ; dataIn should be zero
  1775.     pushlong #srqOutBuffer
  1776.     _SendRequest
  1777.     tax    ; save for a minute
  1778.     lda <KillWithoutMercy
  1779.     bne @CanGoAway
  1780.     txa    ; restore error code
  1781.     bcs @WontGoAway
  1782.     lda srqResultID
  1783.     beq @WontGoAway    ; can't kill them if they return zero, either
  1784.  
  1785. @CanGoAway    lda #0
  1786.     pha
  1787.     pha    ; no name string
  1788.     pei <Temp    ; the user ID
  1789.     pha
  1790.     pha    ; address == 0
  1791.     _AcceptRequests    ; removes the request proc for this guy
  1792.     
  1793.     lda <Filetype
  1794.     cmp #CDAType
  1795.     beq @RemoveCDA
  1796.     cmp #NDAType
  1797.     beq @RemoveNDA
  1798.     bra @NotDA
  1799.  
  1800. @RemoveCDA    ldx #1    ; CDAs
  1801.     lda <Temp    ; the User ID
  1802.     jsr UserIDToDAID    ; returns DA handle low word in X, high in Y
  1803.     phy
  1804.     phx
  1805.     _RemoveCDA
  1806.     bra @NotDA
  1807.     
  1808. @RemoveNDA    ldx #0
  1809.     lda <Temp    ; the user ID
  1810.     jsr UserIDToDAID
  1811.     phy
  1812.     phx
  1813.     _RemoveNDA
  1814.  
  1815. @NotDA    pha    ; space for result
  1816.     pei <Temp
  1817.     lda srqFlags
  1818.     bpl @noZombie
  1819.     pea 1    ; any non-zero or non-$8000 value
  1820.     bra @DoUSD
  1821. @noZombie    pea 0
  1822. @doUSD    _UserShutDown
  1823.     pla
  1824.     bra @MustInitialLoad
  1825.     
  1826. @WontGoAway    lda <TempPrefs
  1827.     and #irKillDuplicates
  1828.     beq @MustInitialLoad
  1829.  
  1830. ;
  1831. ; Here's where we ask the user if we should install a new one even though
  1832. ; they said don't.
  1833. ;
  1834.  
  1835.     lda <TempPrefs
  1836.     and #irIgnoreProblems
  1837.     bne @NoReprieve
  1838.     
  1839.     ldx #irDuplicateWontDieAlert
  1840.     ldy #irDuplicateWontDieAlert>>16
  1841.     jsr DoAlertWindow
  1842.     cmp #1    ; did we get the "go ahead" button?
  1843.     bne @NoReprieve
  1844.     shortm
  1845.     lda >KEYMODREG    ; get modifiers in 8-bit mode
  1846.     longm
  1847.     and #$0040    ; is the option key down?
  1848.     beq @NoReprieve    ; if option key not down, it's an error
  1849.  
  1850. ;
  1851. ; If they pressed option, go ahead and kill it anyway.  Power-user feature
  1852. ; requested by Dave Lyons.
  1853. ;
  1854.  
  1855.     inc <KillWithoutMercy ; temporary flag
  1856.     
  1857.     brl @SendGoAway    ; so send a goodbye message
  1858.     
  1859. @NoReprieve    lda #irDuplicateWontDie ; if not, return an error <sigh>
  1860.     brl ErrorOut
  1861.     
  1862. @MustInitialLoad    
  1863.  
  1864. ;
  1865. ; Before installing a Finder extension, see if we're really in the Finder
  1866. ; and give the user a chance to not do it if we're not.
  1867. ;
  1868.  
  1869.     lda <FileType
  1870.     cmp #GenLoadType
  1871.     bne @ReallyInitialLoad
  1872.     lda <Auxtype
  1873.     and #FindExtAuxMask
  1874.     cmp #FindExtAuxType
  1875.     bne @ReallyInitialLoad ; only do this for Finder extensions
  1876.  
  1877.     lda FSHDataIn
  1878.     ora FSHDataIn+2
  1879.     bne @ReallyInitialLoad
  1880.     
  1881.     lda <TempPrefs
  1882.     and #irIgnoreProblems
  1883.     bne @ReallyInitialLoad
  1884.     
  1885.     ldx #irNoFinderAlert
  1886.     ldy #irNoFinderAlert>>16
  1887.     jsr DoAlertWindow
  1888.     cmp #1
  1889.     beq @ReallyInitialLoad ; should we do this anyway?
  1890.     lda #irNoFinder    ; if not, return the "We're not in Finder" error
  1891.     brl ErrorOut
  1892. ;
  1893. ; Call InitialLoad2 to get the file into memory
  1894. ; If there was no direct page segment, allocate a 4K segment
  1895. ;
  1896.  
  1897. @ReallyInitialLoad    pha    ; word space
  1898.     pha    ; word space
  1899.     pha
  1900.     pha    ; long space
  1901.     pha    ; word space
  1902.     pei <ThisInitID    ; user ID range
  1903.     pei <FilePointer+2
  1904.     pei <FilePointer    ; pointer of pathname
  1905.     pea 1    ; don't use special memory
  1906.     pea 1    ; GS/OS string pathname
  1907.     _InitialLoad2
  1908.     tax    ; save error code
  1909.     pullword <ThisInitID ; now the real ID, not just a range
  1910.     pulllong <StartAddress
  1911.     pullword <DPagePtr
  1912.     pullword <DPageSize
  1913.     bcc @CheckForDP
  1914.     txa    ; restore error code
  1915.     stz <ThisInitID    ; we didn't load anything!
  1916.     brl ErrorOut
  1917.  
  1918. ; Get direct page space if none was included in the file
  1919.  
  1920. @CheckForDP    lda <DPageSize
  1921.     beq @GottaGetMem    ; already allocated
  1922.     bra @TimeToDispatch
  1923.     
  1924. @GottaGetMem    pha
  1925.     pha    ; space for result
  1926.     pushlong #4096    ; 4K
  1927.     pei <ThisInitID
  1928.     pushword #$C015    ; locked, fixed, no bank cross, page aligned, bank
  1929.     lda #0
  1930.     pha
  1931.     pha    ; bank zero
  1932.     _NewHandle
  1933.     tax    ; save error code
  1934.     pulllong <Temp
  1935.     bcc @GotMem
  1936.     txa    ; restore error code
  1937.     brl ErrorOut
  1938.  
  1939. @GotMem    lda [<Temp]
  1940.     sta <DPagePtr
  1941.     lda #4096
  1942.     sta <DPageSize
  1943.     sta <MyDPageFlag
  1944.         
  1945.  
  1946. ; Dispatch to subroutines based on the filetype of the thing to do.
  1947.  
  1948. @TimeToDispatch    lda <FileType
  1949.     ldx #@endDispTable-@DispTable-4
  1950. @checkNextType    cmp @DispTable,x    ; is this the filetype?
  1951.     beq @dispatch    ; yes, then call a routine
  1952.     dex    ; no, then keep checking
  1953.     dex
  1954.     dex
  1955.     dex
  1956.     bpl @checkNextType    ; keep scanning table
  1957.  
  1958. ; This is as good a place as any to put the table
  1959.  
  1960. @DispTable
  1961.     dc.w PermInitType,DoInitsFEs
  1962.     dc.w TempInitType,DoInitsFEs
  1963.     dc.w CDAType,DoCDAs
  1964.     dc.w NDAType,DoNDAs
  1965.     dc.w GenLoadType,DoInitsFEs
  1966.     dc.w DriverType,DoDrivers
  1967. @endDispTable
  1968.  
  1969. @Dispatch    jsr (@DispTable+2,x) ; call the routine
  1970.  
  1971. @PostDispatch    sta <Temp    ; temporarily keep the error code
  1972.     
  1973. ;
  1974. ; If we're being called from our own finderSaysIdle proc, our finderSaysHello
  1975. ; procedure won't get a chance to add this to the NeedsHelloQueue.  It doesn't
  1976. ; really need to, anyway, because we can safely send this request as long
  1977. ; as we're called from that procedure.  So check the IdleGlobalFlag to see if
  1978. ; that's the case and, if so, act on it.
  1979. ;
  1980.  
  1981.     lda IdleGlobalFlag
  1982.     beq @OpenNDAMaybe
  1983.  
  1984.     pea finderSaysHello
  1985.     pea sendToUserID    ; Finder doesn't stop after one
  1986.     pea $0000    ; high word of target == zero
  1987.     pei <ThisInitID    ; low word of target == user ID
  1988.     pushlong FSHdataIn    ; data in from finderSaysHello
  1989.     lda #0
  1990.     pha
  1991.     pha    ; dataOut is nil
  1992.     _SendRequest
  1993.  
  1994. ;
  1995. ; Now, check again to see if this is an NDA -- if it is, and we're supposed to
  1996. ; open it, open it.
  1997. ;
  1998.  
  1999. @OpenNDAMaybe    lda <FileType
  2000.     cmp #NDAType
  2001.     bne @CleanUp
  2002.     lda <TempPrefs
  2003.     and #irDontOpenNDAs    ; this bit is set if we _don't_ open NDAs
  2004.     bne @CleanUp
  2005.     lda <ThisInitID
  2006.     jsr OpenNDAByUserID
  2007.  
  2008. ;
  2009. ; We're done with everything by now, so let's dispose of our memory if we need to
  2010. ;
  2011.  
  2012. @CleanUp    lda <MyDPageFlag
  2013.     bne @DisposeMem
  2014.     lda <Temp
  2015.     bra ErrorOut
  2016.     
  2017. @DisposeMem    lda #0
  2018.     pha
  2019.     pha    ; space for result
  2020.     pha    ; high word of address
  2021.     pei <DPagePtr    ; low word of address
  2022.     _FindHandle
  2023.     _DisposeHandle
  2024.     
  2025.     lda <Temp    ; restore the error code (if any)
  2026.     
  2027. ;
  2028. ; That's it!  Set the error and user ID and return.
  2029. ;
  2030.  
  2031. ErrorOut    pha    ; save error
  2032.     lda <ThisInitID
  2033.     ldy #4
  2034.     sta [<dataOut],y
  2035.     pla
  2036.     sec    ; so the request proc returns it
  2037.     rts
  2038.  
  2039.     EndP
  2040.  
  2041.     EJECT
  2042. *******************************************************************************
  2043. *
  2044. DoDrivers    PROCNAME
  2045. *
  2046. * Description:    Installs a GS/OS driver based on parameters on direct
  2047. *    page.
  2048. *
  2049. *
  2050. * Inputs:    Direct page values all set concerning driver to install
  2051. *
  2052. * Outputs:    Any errors in A.
  2053. *
  2054. * External Refs:
  2055.     with IRData
  2056. *
  2057. * Entry Points:
  2058. *
  2059. *******************************************************************************
  2060.  
  2061.     
  2062. ; First, we allocate a handle with a long pointer to each DIB plus a long count
  2063. ; of how many DIBs there are...
  2064.  
  2065.     lda <Auxtype    ; auxtype low word in A
  2066.     and #$003F    ; mask off all but count of DIBs
  2067.     inc a    ; increase that by one word
  2068.     asl a
  2069.     asl a    ; multiply by four
  2070.     
  2071.     pha
  2072.     pha    ; space for result
  2073.     pea $0000
  2074.     pha    ; size
  2075.     lda IRUserID    ; IR's user ID
  2076.     pha
  2077.     pea $8000    ; the driver will be loaded fixed and
  2078.         ; making this handle fixed will make a
  2079.         ; hole in low memory.  So it's just
  2080.         ; locked.
  2081.     lda #0
  2082.     pha
  2083.     pha    ; any location
  2084.     _NewHandle    ; get the handle
  2085.     plx
  2086.     ply
  2087.     bcc @GotDIBBlock
  2088.     brl @RealDoneDriver    ; get out if error
  2089.     
  2090. @GotDIBBlock    stx <Temp
  2091.     sty <Temp+2
  2092.     ldy #2
  2093.     lda [Temp]
  2094.     sta <DIBPtr
  2095.     lda [Temp],y
  2096.     sta <DIBPtr+2    ; put the pointer into DIBPtr
  2097.     
  2098. ; Now, walk the driver structure and build the DIB Ptr we have to feed to INSTALL_DRIVER
  2099.  
  2100. @WalkDIBs    lda #0
  2101.     sta [DIBPtr]
  2102.     ldy #2
  2103.     sta [DIBPtr],y
  2104.     
  2105.     lda [StartAddress]
  2106.     clc
  2107.     adc <StartAddress
  2108.     sta <TempAlso
  2109.     lda #0
  2110.     adc <StartAddress+2
  2111.     sta <TempAlso+2    ; TempAlso contains pointer to first DIB
  2112.     
  2113.     lda <Auxtype
  2114.     and #$003F    ; get the count again
  2115.     sta <Temp
  2116.     lda #1
  2117.     sta <Temp+2
  2118.     
  2119. ; the cardinal number of DIB we're about to do (Temp+2) is in A
  2120.  
  2121. @CheckTheCount    cmp <Temp
  2122.     beq @CountOK
  2123.     blt @CountOK
  2124.     bra @DoneBuilding
  2125.  
  2126. @CountOK    asl a
  2127.     asl a    ; multiply by four
  2128.     tay
  2129.     lda <TempAlso
  2130.     sta [DIBPtr],y
  2131.     iny
  2132.     iny
  2133.     lda <TempAlso+2
  2134.     sta [DIBPtr],y
  2135.     
  2136. ; now we make TempAlso point to the next DIB
  2137.  
  2138.     lda [TempAlso]
  2139.     tax
  2140.     ldy #2
  2141.     lda [TempAlso],y
  2142.     sta <TempAlso+2
  2143.     stx <TempAlso
  2144.     
  2145.     inc <Temp+2
  2146.     lda <Temp+2
  2147.     bra @CheckTheCount
  2148.     
  2149. ; we have the DIBPtr, now we feed it to INSTALL_DRIVER
  2150.  
  2151. @DoneBuilding    lda <Temp
  2152.     sta [DIBPtr]
  2153.  
  2154. ;
  2155. ; We set warm_cold_flag so new drivers think this is a cold start and do the right
  2156. ; thing for them.
  2157. ;
  2158.  
  2159.     lda >warm_cold_flag
  2160.     sta <TempAlso
  2161.     and #$FFFE
  2162.     sta >warm_cold_flag    ; tell drivers it's a cold startup
  2163.     
  2164.     shortm
  2165.     lda >$E0C068
  2166.     pha
  2167.     lda >$E0C08B
  2168.     lda >$E0C08B
  2169.     longmx
  2170.     
  2171.     ldx <DIBPtr
  2172.     ldy <DIBPtr+2
  2173.     jsl INSTALL_DRIVER    ; INSTALL_DRIVER
  2174.     sta <Temp
  2175.     
  2176.     shortm
  2177.     lda >$E0C083
  2178.     lda >$E0C083
  2179.     pla
  2180.     sta >$E0C068
  2181.     longmx
  2182.     
  2183.     lda <Temp
  2184.     bne @DoneFlagDriver    ; don't do it if error
  2185.     
  2186. ;
  2187. ; Now, to activate the driver we have to give the Device Manager a call, and not just
  2188. ; any call, but one that causes drivers to be called.  DInfo will work.
  2189. ;
  2190.     
  2191.     _DInfoGS DInfoParms    ; DInfo call to dev #1
  2192.     
  2193. ; Hey, we're done!
  2194.  
  2195.  
  2196. @DoneFlagDriver    lda <TempAlso    ; the old flag value
  2197.     sta >warm_cold_flag
  2198.     
  2199. @DoneGotMem    pha
  2200.     pha
  2201.     pei <DIBPtr+2
  2202.     pei <DIBPtr
  2203.     _FindHandle
  2204.     _DisposeHandle
  2205.  
  2206.     lda #0
  2207. @RealDoneDriver    rts
  2208.     
  2209.     EndP
  2210.  
  2211.     EJECT
  2212. *******************************************************************************
  2213. *
  2214. DoCDAs    PROCNAME
  2215. *
  2216. * Description:    Installs CDAs given parameters on direct page.
  2217. *
  2218. *
  2219. * Inputs:    Direct page has all the necessary stuff.
  2220. *
  2221. * Outputs:    Error code in A.
  2222. *
  2223. * External Refs:    
  2224.     with IRData
  2225. *
  2226. * Entry Points:
  2227. *
  2228. *******************************************************************************
  2229.  
  2230.     pha
  2231.     pha    ; space for result
  2232.     pei <StartAddress+2
  2233.     pei <StartAddress
  2234.     _FindHandle
  2235.     _InstallCDA
  2236.     
  2237. ;
  2238. ; Now, we can't necessarily call _DeskShutDown to breathe the gift of life into the
  2239. ; CDA, so we find the shutdown pointer and call it die-reckly.
  2240. ;
  2241.  
  2242.     lda [<StartAddress]    ; length byte of name string
  2243.     and #$00FF    ; mask it off
  2244.     clc
  2245.     adc #5    ; account for length byte and Entry pointer
  2246.     adc <StartAddress
  2247.     sta <Temp
  2248.     lda <StartAddress+2
  2249.     adc #0    ; is this really necessary?
  2250.     sta <Temp+2    ; now Temp points to the ShutDown pointer
  2251.     
  2252.     lda [<Temp]
  2253.     sta @JSLCDA+1
  2254.     ldy #1
  2255.     lda [<Temp],y
  2256.     sta @JSLCDA+2    ; self-modify the JSL
  2257.     
  2258.     lda #0
  2259.     tax
  2260.     tay
  2261.     
  2262. @JSLCDA    jsl $000000    ; call the shutdown routine
  2263.  
  2264. ;
  2265. ; Actually, that should do it.  Let's get out of here.
  2266. ;
  2267.  
  2268. @ReturnFromCDA    lda #0
  2269.     rts
  2270.     
  2271.     EndP
  2272.     
  2273.     EJECT
  2274. *******************************************************************************
  2275. *
  2276. DoNDAs    PROCNAME
  2277. *
  2278. * Description:    Installs the NDA and breathes life into it.
  2279. *
  2280. *
  2281. * Inputs:    All the goodies on direct page.
  2282. *
  2283. * Outputs:    Any errors in A.
  2284. *
  2285. * External Refs:
  2286.     with IRData
  2287.     IMPORT UserIDToDAID
  2288. *
  2289. * Entry Points:
  2290. *
  2291. *******************************************************************************
  2292.  
  2293.     pha
  2294.     pha    ; space for result
  2295.     pei <StartAddress+2
  2296.     pei <StartAddress
  2297.     _FindHandle
  2298.     _InstallNDA
  2299.     
  2300. ;
  2301. ; Next, give this NDA a "DeskShutdown" call just like it was boot time.  Since
  2302. ; we can't actually shut down the Desk Manager (any running application like
  2303. ; the Finder would be really annoyed), we send the DA an individual "shutdown"
  2304. ; code with the new CallDeskAcc call.
  2305. ;
  2306.  
  2307.     lda <ThisInitID
  2308.     ldx #0
  2309.     jsr UserIDToDAID
  2310.     
  2311.     pha    ; space for result
  2312.     pea $0002    ; call the Init routine by reference number
  2313.     pea $0000    ; high word of reference == 0
  2314.     pha    ; low word == NDA ID
  2315.     lda #0
  2316.     pha    ; zero == shutdown call
  2317.     pha
  2318.     pha    ; nothing in XY
  2319.     _CallDeskAcc
  2320.     pla    ; don't care about this
  2321.  
  2322. ;
  2323. ; Test to see if we need to do the Apple menu futz -- we don't if the preferences
  2324. ; say we don't, and we don't if the Desk Manager isn't active.
  2325. ;
  2326.  
  2327.     lda <TempPrefs
  2328.     and #irDontOpenNDAs
  2329.     beq @TestForFutz
  2330.     brl @DoneNDA
  2331.     
  2332. @TestForFutz    pha
  2333.     _DeskStatus
  2334.     pla
  2335.     bne @TimeForFutz
  2336.     brl @DoneNDA
  2337.     
  2338. ;
  2339. ; It's time.  First, send it a "startup" code, then do the futz to refix the Apple
  2340. ; menu without leaving the application.
  2341. ;
  2342.  
  2343. @TimeForFutz    lda <ThisInitID
  2344.     ldx #0
  2345.     jsr UserIDToDAID
  2346.     
  2347.     pha    ; space for result
  2348.     pea $0002    ; call the Init routine by reference number
  2349.     pea $0000    ; high word of reference == 0
  2350.     pha    ; low word == NDA ID
  2351.     pea $0001    ; one == startup call
  2352.     lda #0
  2353.     pha
  2354.     pha    ; nothing in XY
  2355.     _CallDeskAcc
  2356. ;    pla    ; don't care about this
  2357.  
  2358. @DoTheFutz    pha
  2359. ;    pha    ; space for result
  2360.     _GetSysBar
  2361.     pulllong <TempAlso
  2362.     
  2363.     lda [<TempAlso]
  2364.     tax
  2365.     ldy #2
  2366.     lda [<TempAlso],y
  2367.     sta <TempAlso+2
  2368.     stx <TempAlso    ; TempAlso points to menu bar record
  2369.  
  2370.     ldy #$28    ; offset to list of menu handles
  2371.     lda [<TempAlso],y
  2372.     sta <Temp
  2373.     iny
  2374.     iny
  2375.     lda [<TempAlso],y
  2376.     sta <Temp+2    ; Temp now has handle of first menu
  2377.     
  2378.     lda [<Temp]
  2379.     tax
  2380.     ldy #2
  2381.     lda [<Temp],y
  2382.     sta <Temp+2
  2383.     stx <Temp    ; now Temp points to first menu
  2384.     
  2385.     lda [<Temp]    ; that's the ID of the first menu
  2386.     sta <Temp    ; there it is
  2387.     
  2388.     pha
  2389.     _GetNumNDAs
  2390.     pla
  2391.     dec a    ; don't count the NDA we just installed!
  2392.     sta <Temp+2
  2393.     
  2394. ;
  2395. ; By the way, this also depends on the fact that all the NDAs have menu items
  2396. ; that are numbered from 1 to GetNumNDAs.
  2397. ;
  2398.  
  2399. @FutzLoop    pei <Temp+2
  2400.     _DeleteMItem
  2401.     dec <Temp+2
  2402.     bne @FutzLoop
  2403.     
  2404.     pei <Temp    ; ID of the Apple menu
  2405.     _FixAppleMenu
  2406.     
  2407.     lda #0
  2408.     pha    ; calculate width
  2409.     pha    ; calculate height
  2410.     pei <Temp    ; ID of the menu
  2411.     _CalcMenuSize
  2412.     
  2413. ;
  2414. ; That's it!
  2415. ;
  2416.  
  2417. @DoneNDA    lda #0
  2418.     rts
  2419.     
  2420.     EndP
  2421.     
  2422.  
  2423.     EJECT
  2424. *******************************************************************************
  2425. *
  2426. DoInitsFEs    PROCNAME
  2427. *
  2428. * Description:    Installs and executes permanent and temporary inits and
  2429. *    Finder Extensions.  The variations between the three
  2430. *    are so minor that one subroutine can handle them all.
  2431. *
  2432. *
  2433. * Inputs:    File information on direct page.
  2434. *
  2435. * Outputs:    Any errors in A.
  2436. *
  2437. * External Refs:
  2438.     with IRData
  2439.     IMPORT AddIDToQueue
  2440. *
  2441. * Entry Points:
  2442. *
  2443. *******************************************************************************
  2444.  
  2445. ;
  2446. ; We call these things with the user ID in A, zero in X/Y and the direct page and
  2447. ; stack set up.  FEs and permanent inits have a word on the stack above the RTL
  2448. ; address -- if they change the low bit from zero to one, the thing is shut down
  2449. ; on returning.  We'll push a $0001 there for temporary inits so we can share
  2450. ; the same code, more or less.
  2451. ;
  2452.  
  2453.     tsc
  2454.     sta MyStack
  2455.     tdc
  2456.     sta MyDP    ; save my stack and DP values
  2457.     
  2458.     lda <DPageSize
  2459.     dec a
  2460.     clc
  2461.     adc <DPagePtr
  2462.     tcs    ; got new stack pointer
  2463.  
  2464.     ldx #0
  2465.     lda <FileType
  2466.     cmp #TempInitType
  2467.     bne @NotTempInit
  2468.     inx
  2469. @NotTempInit    phx    ; value above RTL address on stack
  2470.  
  2471.     pei <ThisInitID
  2472.     ldx <StartAddress
  2473.     ldy <StartAddress+1
  2474.     
  2475.     lda <DPagePtr
  2476.     tcd    ; new direct page in -- can't use DP anymore
  2477.     
  2478.     txa
  2479.     sta >@InitJSL+1
  2480.     tya
  2481.     sta >@InitJSL+2    ; self-modify the JSL to point to the right place
  2482.     
  2483.     pea $FFFF
  2484.     plb
  2485.     plb    ; this sets the DBR to $FFFF, which is what
  2486.         ; GS/OS does and should help you find bugs faster.
  2487.     
  2488.     pla    ; the user ID
  2489.     ldx #0
  2490.     txy    ; zeros in X and Y, user ID in the accumulator
  2491.     
  2492. @InitJSL    jsl $000000    ; self-modified
  2493.  
  2494. ;
  2495. ; Here we are, back from the whatever it was we just called.
  2496. ;
  2497.  
  2498.     plx    ; get result of "do we shutdown"
  2499.     lda >MyStack
  2500.     tcs
  2501.     lda >MyDP
  2502.     tcd    ; got my stack frame back now
  2503.     
  2504.     phk
  2505.     plb    ; set the B register back for us
  2506.     
  2507.     txa    ; result word from stack
  2508.     and #$0001
  2509.     beq @CheckForFE    ; if no shutdown, see if this is a Finder Ext.
  2510.     
  2511.     lda #0
  2512.     pha    ; space for result
  2513.     pei <ThisInitID
  2514.     pha    ; flag of zero -- get rid of it
  2515.     _UserShutDown
  2516.     pla    ; discard this
  2517.     bra @DoneInitFE
  2518.     
  2519. @CheckForFE    lda <Filetype
  2520.     cmp #GenLoadType    ; is this a Finder Extension?
  2521.     bne @DoneInitFE
  2522.     
  2523. ;
  2524. ; If we're here, we might need to store the user ID of this so we can kill it later
  2525. ;
  2526.  
  2527.     lda <TempPrefs
  2528.     and #irKillFinderExts
  2529.     beq @DoneInitFE
  2530.     
  2531.     lda <ThisInitID
  2532.     ldx #FinderExtQueue
  2533.     jsr AddIDToQueue
  2534.     
  2535. @DoneInitFE    lda #0
  2536.     rts
  2537.  
  2538.     EndP
  2539.  
  2540.     EJECT
  2541. *******************************************************************************
  2542. *
  2543. IRSeesIdle    PROCNAME
  2544. *
  2545. * Description:    We get to here on finderSaysIdle.  Here's where we have to
  2546. *    look through all the IDs we have queued up and send
  2547. *    finderSaysHello to each of them.  We also dispatch all
  2548. *    the programs saved in the DelayedStartQueue; we can install
  2549. *     them now because Finder can now accept their calls in
  2550. *    response to finderSaysHello.
  2551. *
  2552. *
  2553. * Inputs:    None
  2554. *
  2555. * Outputs:    None
  2556. *
  2557. * External Refs:
  2558.     with IRData
  2559.     IMPORT GetQueuePtr
  2560.     IMPORT GetQueueHandle
  2561.     IMPORT KillThisQueue
  2562. *
  2563. * Entry Points:
  2564. *
  2565. *******************************************************************************
  2566.  
  2567. QueuePtr    equ TempAlso
  2568.  
  2569. ;
  2570. ; Try to get out quickly if we have no things to dispatch
  2571. ;
  2572.  
  2573.     ldx #NeedsHelloQueue+lockQueueHandle
  2574.     jsr GetQueueHandle
  2575.     lda <QueuePtr
  2576.     ora <QueuePtr+2
  2577.     bne @StuffToDo
  2578.     bra @CheckDelayedStart
  2579.     
  2580. @StuffToDo    lda [<QueuePtr]
  2581.     tax
  2582.     ldy #2
  2583.     lda [<QueuePtr],y
  2584.     sta <QueuePtr+2
  2585.     stx <QueuePtr    ; faster than GetQueuePtr
  2586.  
  2587.     lda [<QueuePtr]
  2588.     inc a    ; account for overhead words
  2589.     asl a    ; double it
  2590.     tay
  2591.     sty <Temp+2
  2592.             
  2593. @DispatchLoop    pea finderSaysHello
  2594.     pea sendToUserID    ; Finder doesn't stop after one
  2595.     pea $0000    ; high word of target == zero
  2596.     ldy <Temp+2    ; the index
  2597.     lda [<QueuePtr],y
  2598.     pha    ; low word of target == user ID
  2599.     pushlong FSHdataIn    ; data in from finderSaysHello
  2600.     lda #0
  2601.     pha
  2602.     pha    ; dataOut is nil
  2603.     _SendRequest
  2604.     
  2605.     dec <Temp+2
  2606.     dec <Temp+2    ; bump the index
  2607.     lda #2    ; this index value means we're done
  2608.     cmp <Temp+2
  2609.     bne @DispatchLoop
  2610.     
  2611. ;
  2612. ; We don't unlock the handle because we're going to dispose of it anyway
  2613. ;
  2614.  
  2615.     ldx #NeedsHelloQueue
  2616.     jsr KillThisQueue
  2617.     
  2618. ;
  2619. ; Now check to see if there's anything that needs a delayed start.
  2620. ;
  2621.  
  2622. @CheckDelayedStart    NAME
  2623.     ldx #DelayedStartQueue+lockQueueHandle
  2624.     jsr GetQueueHandle
  2625.     lda <QueuePtr
  2626.     ora <QueuePtr+2
  2627.     bne @MoreStuffToDo
  2628.     brl @DoNothing
  2629.     
  2630. @MoreStuffToDo    lda [<QueuePtr]
  2631.     tax
  2632.     ldy #2
  2633.     lda [<QueuePtr],y
  2634.     sta <QueuePtr+2
  2635.     stx <QueuePtr    ; faster than GetQueuePtr
  2636.  
  2637.     lda [<QueuePtr]
  2638.     inc a    ; account for overhead words
  2639.     asl a    ; double it
  2640.     tay
  2641.     sty <Temp+2
  2642.             
  2643. ;
  2644. ; Now, at this point, we point to a queue entry that contains the preferences
  2645. ; for this install.  The next (decremented) queue entry contains the user ID
  2646. ; for the thing we're trying to install.  Get the preferences first and
  2647. ; deal with the file next.
  2648. ;
  2649. ; Y == INDEX ON ENTRY TO TOP OF LOOP!
  2650. ;
  2651.  
  2652.  
  2653. @DispatchLoop2    lda [<QueuePtr],y    ; the preferences
  2654.     sta InputFlags    ; keep this for a second
  2655.     dey
  2656.     dey
  2657.     sty <Temp+2    ; index now points to user ID
  2658.     
  2659.     pha
  2660.     pha    ; space for result
  2661.     lda [<QueuePtr],y
  2662.     pha    ; user ID
  2663.     pea $0001    ; always file #1
  2664.     _LGetPathname2
  2665.     pla
  2666.     sta GFIPathPtr
  2667.     sta InputPath
  2668.     pla
  2669.     sta GFIPathPtr+2    ; put this in our GetFileInfo block
  2670.     sta InputPath+2    ; and in our parameters to IR
  2671.     
  2672.     _GetFileInfoGS GFIParms ; file must exist
  2673.     bcs @NextItem    ; OK, if an error, we won't install
  2674.     
  2675.     lda GFIFileType
  2676.     sta InputType
  2677.     
  2678.     lda GFIAuxType
  2679.     sta InputAuxType
  2680.     lda GFIAuxType+2
  2681.     sta InputAuxType+2
  2682.     
  2683.     inc IdleGlobalFlag    ; tell IRGetsToWork it's OK to do this!
  2684.     pushword #askIRToInstall
  2685.     pushword #sendToName+stopAfterOne
  2686.     pushlong #IRString
  2687.     pushlong #InputFlags ; address of input buffer
  2688.     pushlong #OutputCount ; address of output buffer
  2689.     _SendRequest    ; and let's do it again!
  2690.     stz IdleGlobalFlag    ; clear this puppy fast!
  2691.     
  2692. ;
  2693. ; We can't do anything about errors, so we don't worry too much.
  2694. ;
  2695.  
  2696. @NextItem    dec <Temp+2
  2697.     dec <Temp+2    ; bump the index
  2698.     ldy <Temp+2    ; keep this index in Y!
  2699.     lda #2    ; this index value means we're done
  2700.     cmp <Temp+2
  2701.     bne @DispatchLoop2
  2702.  
  2703.     ldx #DelayedStartQueue
  2704.     jsr KillThisQueue
  2705.     
  2706.     bra @TimeToLeave
  2707.     
  2708. @DoNothing    stz <result    ; denying the request
  2709.  
  2710. @TimeToLeave    lda #0
  2711.     clc
  2712.     rts    ; just to be nice.
  2713.     
  2714. InputFlags    dc.w 0
  2715. InputPath    dc.l 0
  2716. InputType    dc.w 0
  2717. InputAuxType    dc.l 0
  2718.  
  2719. OutputCount    dc.w 0
  2720. OutputResult     dc.w 0
  2721. OutputID    dc.w 0
  2722.     
  2723.     EndP
  2724.  
  2725.     EJECT
  2726. *******************************************************************************
  2727. *
  2728. IRGoesAway    PROCNAME
  2729. *
  2730. * Description:    This is our response to srqGoAway -- return our user ID
  2731. *    after killing all the Finder Extensions we may have
  2732. *    lying around.
  2733. *
  2734. *
  2735. * Inputs:    None
  2736. *
  2737. * Outputs:    None
  2738. *
  2739. * External Refs:
  2740.     with IRData
  2741.     IMPORT KillQueueEntries
  2742.     IMPORT GetQueueHandle
  2743.     IMPORT NotifyProcCode
  2744. *
  2745. * Entry Points:
  2746. *
  2747. *******************************************************************************
  2748.  
  2749. QueuePtr    equ TempAlso
  2750.  
  2751.     lda IRBusyFlag
  2752.     bne @CantLeave
  2753.     
  2754. @CheckHelloQ    ldx #NeedsHelloQueue
  2755.     jsr GetQueueHandle
  2756.     lda <QueuePtr
  2757.     ora <QueuePtr+2
  2758.     beq @GoingAway    ; don't go away if people need hellos
  2759.     
  2760. @CantLeave    lda #0    ; accepting with user ID of zero
  2761.     bra @Exit
  2762.  
  2763. @GoingAway    lda #1    ; non-zero
  2764.     ldx #FinderExtQueue
  2765.     jsr KillQueueEntries
  2766.     
  2767.     lda PrefsPathPtr
  2768.     ora PrefsPathPtr+2
  2769.     beq @NoPathHandle
  2770.  
  2771.     pha
  2772.     pha    ; space for _FindHandle result
  2773.     pushlong PrefsPathPtr
  2774.     _FindHandle
  2775.     _DisposeHandle    ; get rid of our pathname handle
  2776.     stz PrefsPathPtr
  2777.     stz PrefsPathPtr+2
  2778.  
  2779. ;
  2780. ; Call our "Switch to P8" notify proc to close out all our resource stuff
  2781. ;
  2782.  
  2783. @NoPathHandle    jsl NotifyProcCode
  2784.     
  2785.     _DelNotifyProcGS NotifyProcParms
  2786.  
  2787.     lda IRUserID
  2788. @Exit    ldy #2
  2789.     sta [<dataOut],y
  2790.     iny
  2791.     iny
  2792.     lda #0    ; not restartable from memory
  2793.     sta [<dataOut],y
  2794.     
  2795. ;
  2796. ; In fact, I think we _are_ restartable from memory, but I don't have the
  2797. ; time to test this, and it's better to be safe than sorry.
  2798. ;
  2799.     
  2800.     clc
  2801.     rts
  2802.     
  2803. RemoveBuffer    dc.w 0    ; recvCount
  2804.     dc.w 0    ; Finder result
  2805.     
  2806.     EndP
  2807.  
  2808.     EJECT
  2809. *******************************************************************************
  2810. *
  2811. KillQueueEntries    PROCNAME
  2812. *
  2813. * Description:    Sends srqGoAway to all user IDs in a queue.  A is non-
  2814. *    zero if we need to send them finderSaysGoodbye as well.
  2815. *
  2816. *
  2817. * Inputs:    A is non-zero if we send finderSaysGoodbye as well as
  2818. *    srqGoAway.  X contains the queue number for the queue
  2819. *    to use.
  2820. *
  2821. * Outputs:    None.
  2822. *
  2823. * External Refs:
  2824.     with IRData
  2825.     IMPORT GetQueuePtr
  2826.     IMPORT GetQueueHandle
  2827.     IMPORT KillThisQueue
  2828.     IMPORT AddIDToQueue
  2829. *
  2830. * Entry Points:
  2831. *
  2832. *******************************************************************************
  2833.  
  2834. QueuePtr    equ TempAlso
  2835.  
  2836.     pei <QueuePtr+2
  2837.     pei <QueuePtr    ; save this
  2838.     sta <Temp    ; keep this around for a while
  2839.     stx QueueNum
  2840.     
  2841.     txa
  2842.     ora #lockQueueHandle
  2843.     tax
  2844.     jsr GetQueueHandle    ; returns handle in TempAlso
  2845.     
  2846.     lda <QueuePtr
  2847.     ora <QueuePtr+2
  2848.     bne @FEsToKill
  2849.     brl @NoFEs    ; handle not locked if it's not a handle
  2850.     
  2851. ;
  2852. ; OK, if we have things to kill, we can take a bit more time about it
  2853. ;
  2854.  
  2855. @FEsToKill    ldx QueueNum
  2856.     jsr GetQueuePtr    ; get the whole thing this time
  2857.     
  2858.     lda [<QueuePtr]
  2859.     inc a    ; account for overhead words
  2860.     asl a    ; double it
  2861.     tay
  2862.     sty <Temp+2
  2863.     pea $FFFF    ; marker word for stack stuff
  2864.             
  2865. @KillItLoop    lda <Temp
  2866.     beq @SendGoAway
  2867.     
  2868. @SendGoodbye    pea finderSaysGoodbye
  2869.     pea sendToUserID    ; don't stop after one in case they have
  2870.         ; multiple request procedures
  2871.     pea 0
  2872.     ldy <Temp+2    ; the index
  2873.     lda [<QueuePtr],y
  2874.     pha    ; user ID
  2875.     lda #0
  2876.     pha
  2877.     pha    ; dataIn is nil
  2878.     pha
  2879.     pha    ; dataOut is nil
  2880.     _SendRequest
  2881.     
  2882. @SendGoAway    stz srqOutBuffer
  2883.     stz srqFlags
  2884.     stz srqResultID
  2885.     pea srqGoAway
  2886.     pea sendToUserID+stopAfterOne
  2887.     pea 0000    ; high word of target (user ID)
  2888.     ldy <Temp+2    ; the index
  2889.     lda [<QueuePtr],y
  2890.     pha    ; user ID
  2891.     lda #0
  2892.     pha
  2893.     pha    ; dataIn is nil
  2894.     pushlong #srqOutBuffer ; dataOut pointer
  2895.     _SendRequest
  2896.     
  2897. ;
  2898. ; If the request wasn't accepted, or if the resulting ID is zero (2.0a4),
  2899. ; we can't shut it down
  2900. ;
  2901.  
  2902.     bcs @CantShutDown
  2903.     lda srqResultID
  2904.     beq @CantShutDown
  2905.     
  2906.     ldx #0    
  2907.     phx
  2908.     phx    ; name pointer == NIL
  2909.     lda srqResultID
  2910.     pha
  2911.     phx
  2912.     phx
  2913.     _AcceptRequests    ; take this request proc away
  2914.     
  2915.     pha    ; space for result
  2916.     lda srqResultID    ; result ID still there
  2917.     pha    ; user ID
  2918.     lda srqFlags
  2919.     and #$8000    ; other bits are reserved
  2920.     lsr a    ; makes $8000 into "non-zero" for loader
  2921.     pha    ; the flags
  2922.     _UserShutDown
  2923.     pla    ; discard this
  2924.     bra @NextEntry
  2925.     
  2926. @CantShutDown    ldy <Temp+2
  2927.     lda [<QueuePtr],y    ; the user ID
  2928.     pha    ; save it on the stack
  2929.  
  2930. @NextEntry    dec <Temp+2
  2931.     dec <Temp+2    ; bump the index
  2932.     lda #2    ; this index value means we're done
  2933.     cmp <Temp+2
  2934.     beq @DoneLoop
  2935.     brl @KillItLoop
  2936.     
  2937. @DoneLoop    ldx QueueNum
  2938.     jsr KillThisQueue
  2939.     
  2940. ;
  2941. ; Okay, now we've tried to kill everything in the queue and we've pushed
  2942. ; the user IDs of any items that wouldn't go away.  If any such items exist,
  2943. ; we need to recreate them in the queue for trying again later.
  2944. ;
  2945.  
  2946. @RecreateQ    pla
  2947.     cmp #$FFFF    ; is it our flag word?
  2948.     beq @NoFEs
  2949.     ldx QueueNum
  2950.     jsr AddIDToQueue
  2951.     bra @RecreateQ
  2952.  
  2953. @NoFEs    pulllong QueuePtr
  2954.     lda #0
  2955.     clc
  2956.     rts    ; just to be nice.
  2957.     
  2958. QueueNum    dc.w 0    ; local storage
  2959.     
  2960.     EndP
  2961.  
  2962.     EJECT
  2963. *******************************************************************************
  2964. *
  2965. GetPrefsFromDisk    PROCNAME
  2966. *
  2967. * Description:    Gets the preferences from the disk file into our data
  2968. *    area.  Also sets up the pathname to the preferences file,
  2969. *    the parameter blocks, etc.
  2970. *
  2971. *
  2972. * Inputs:    None.
  2973. *
  2974. * Outputs:    Error in A/carry.
  2975. *
  2976. * External Refs:
  2977.     with IRData
  2978.     IMPORT MakePrefsPath
  2979. *
  2980. * Entry Points:    None.
  2981. *
  2982. *******************************************************************************
  2983.  
  2984. ;
  2985. ; First, set up the default preferences in both prefs locations so if we can't
  2986. ; get the disk preferences, we have something valid.
  2987. ;
  2988.  
  2989.     lda #irDefaultPrefs
  2990.     sta DiskPrefs
  2991.     sta LocalPrefs
  2992.  
  2993. ;
  2994. ; Next, construct the pathname to the preferences file.  
  2995. ;
  2996.  
  2997.     jsr MakePrefsPath    ; this is gnarly and needs to be called more than
  2998.         ; once
  2999.     bcs PrefsError
  3000.  
  3001. ;
  3002. ; OK.  Now, try to open the file and read the preferences.
  3003. ;
  3004.  
  3005.     lda #readEnable
  3006.     sta OpenAccess
  3007.     _OpenGS OpenParms
  3008.     bcs PrefsError
  3009.     
  3010.     lda OpenRefnum
  3011.     sta RWrefnum
  3012.     sta CloseRefnum
  3013.     _ReadGS RWParms
  3014.     
  3015. ;
  3016. ; 2.0a4 -- remember to close the file, dummy
  3017. ;
  3018.  
  3019.     php
  3020.     pha    ; save error state
  3021.     _CloseGS CloseParms
  3022.     pla
  3023.     plp    ; return error from Read, not Close
  3024.     bcs PrefsError
  3025.     
  3026.     lda DiskPrefs
  3027.     sta LocalPrefs
  3028.     
  3029. ;
  3030. ; That's it.
  3031. ;
  3032.  
  3033.     lda #0
  3034.     clc
  3035. PrefsError    rts
  3036.     
  3037.     EndP
  3038.  
  3039.     EJECT
  3040. *******************************************************************************
  3041. *
  3042. PutPrefsToDisk    PROCNAME
  3043. *
  3044. * Description:    Writes the preferences in DiskPrefs to disk.
  3045. *
  3046. *
  3047. * Inputs:    None
  3048. *
  3049. * Outputs:    Error in A/carry
  3050. *
  3051. * External Refs:
  3052.     with IRData
  3053.     IMPORT MakePrefsPath
  3054. *
  3055. * Entry Points:    None.
  3056. *
  3057. *******************************************************************************
  3058.  
  3059.     jsr MakePrefsPath    ; make sure we have the right path
  3060.     bcs PutPrefsError
  3061.     
  3062. @OpenFile    lda #writeEnable
  3063.     sta OpenAccess
  3064.     _OpenGS OpenParms
  3065.     bcc @NowWrite
  3066.     cmp #$0046    ; is it file not found?
  3067.     sec    ; because the cmp affects it
  3068.     bne PutPrefsError
  3069.     
  3070. @CreateFile    _CreateGS CreateParms
  3071.     bcc @OpenFile
  3072.     bcs PutPrefsError
  3073.     
  3074. @NowWrite    lda OpenRefnum
  3075.     sta RWrefnum
  3076.     sta CloseRefNum
  3077.     _WriteGS RWParms
  3078.     
  3079.     php    ; now close the file regardless of error
  3080.     pha    ; save error state
  3081.     _CloseGS CloseParms
  3082.     pla
  3083.     plp    ; return write error, not close.
  3084.     bcs PutPrefsError
  3085.  
  3086.     lda DiskPrefs
  3087.     sta LocalPrefs
  3088.     
  3089. ;
  3090. ; That's it.
  3091. ;
  3092.  
  3093.     lda #0
  3094.     clc
  3095. PutPrefsError    rts
  3096.     
  3097.     EndP
  3098.  
  3099.     EJECT
  3100. *******************************************************************************
  3101. *
  3102. IRReturnsPreferences PROCNAME
  3103. *
  3104. * Description:    Returns preferences in the third word of the buffer
  3105. *    pointed to by dataOut.  If the low bit of dataIn is
  3106. *    set, we read the prefs from disk before returning them.
  3107. *
  3108. *
  3109. * Inputs:    low bit of dataIn set == read from disk
  3110. *
  3111. * Outputs:    dataOut +004  == preferences
  3112. *    Error in A/carry
  3113. *
  3114. * External Refs:
  3115.     with IRData
  3116. *
  3117. * Entry Points:
  3118. *
  3119. *******************************************************************************
  3120.  
  3121.     lda <dataIn
  3122.     ror a
  3123.     bcc @justReturnPrefs
  3124.     
  3125.     jsr GetPrefsFromDisk
  3126.     bcs @PrefsError
  3127.     
  3128. @justReturnPrefs    lda LocalPrefs
  3129.     ldy #4
  3130.     sta [<dataOut],y
  3131.     
  3132.     lda #0
  3133.     sec
  3134. @PrefsError    rts
  3135.  
  3136.     EndP
  3137.     
  3138.     EJECT
  3139. *******************************************************************************
  3140. *
  3141. IRSetsPreferences    PROCNAME
  3142. *
  3143. * Description:    Takes preferences in the low word of dataIn and sets them
  3144. *    in memory.  If the low bit (irDoDiskPrefs) is set, they're
  3145. *    written to disk as well, if possible, but they're always
  3146. *    written to memory even if disk errors occur.
  3147. *
  3148. *
  3149. * Inputs:    New prefs in dataIn
  3150. *
  3151. * Outputs:    Second word of dataOut == result code
  3152. *
  3153. * External Refs:
  3154.     with IRData
  3155. *
  3156. * Entry Points:
  3157. *
  3158. *******************************************************************************
  3159.  
  3160.     lda <dataIn
  3161.     and #$FFFE    ; clear out bit zero first!
  3162.     sta LocalPrefs
  3163.     lda <dataIn
  3164.     ror a
  3165.     bcc @justSetPrefs
  3166.     
  3167.     asl a    ; shift back and clear low bit at once
  3168.     sta DiskPrefs
  3169.     jsr PutPrefsToDisk
  3170.     bcs @PrefsError
  3171.     
  3172. @justSetPrefs    lda #0
  3173.     sec
  3174. @PrefsError    rts
  3175.  
  3176.     EndP
  3177.     
  3178.  
  3179.     EJECT
  3180. *******************************************************************************
  3181. *
  3182. MakePrefsPath    PROCNAME
  3183. *
  3184. * Description:    Creates the pathname used for the preferences file and
  3185. *    propagates it throughout the parameter blocks.  The order
  3186. *    used to create the path is as follows:
  3187. *
  3188. *    1)  If this file is on AppleShare, preferences are in
  3189. *        the user folder.
  3190. *    2)  If this file is not on a network volume, prefs are
  3191. *        stored with this file.
  3192. *
  3193. * Inputs:    Carry is set to force local path instead of AppleShare.
  3194. *    Carry set also forces a path rebuild.
  3195. *
  3196. * Outputs:    None
  3197. *
  3198. * External Refs:
  3199.     with IRData
  3200. *
  3201. * Entry Points:
  3202. *
  3203. *******************************************************************************
  3204.  
  3205. ;
  3206. ; First see if we've already done this...
  3207. ;
  3208.  
  3209. @CheckPath    lda PrefsPathPtr
  3210.     ora PrefsPathPtr+2
  3211.     beq @NoPath
  3212. @WereDone    brl GotPrefsPath
  3213.  
  3214. @NoPath    pha
  3215.     pha    ; space for result
  3216.     lda IRUserID
  3217.     pha    ; our ID
  3218.     pea $0001    ; file number always == 1
  3219.     _LGetPathname2
  3220.     tax
  3221.     pulllong <Temp
  3222.     txa    ; preserve error code
  3223.     
  3224.     bcc @0
  3225.     brl PrefsPathError
  3226.     
  3227. @0    lda <Temp
  3228.     sta GFIPathPtr
  3229.     lda <Temp+2
  3230.     sta GFIPathPtr+2    ; get ready for GetFileInfo
  3231.     
  3232.     _GetFileInfoGS GFIParms
  3233.     bcc @1
  3234.     brl PrefsPathError
  3235.     
  3236. @1    lda OptionListFSID
  3237.     cmp #appleShareFSID    ; is our file on AppleShare
  3238.     beq @DoUserPath
  3239.     brl @DoLocalPath
  3240.     
  3241. ;
  3242. ; If we get here, we need to get the user path from the AppleShare FST.  The call
  3243. ; is simple; we just set up the strange local variables like we were looking at
  3244. ; a local pathname and use much of the same code.  First, get the path.
  3245. ;
  3246.  
  3247. @DoUserPath    _FSTSpecific UserPathParms
  3248.     bcs @DoLocalPath    ; do this locally if data unavailable
  3249.     
  3250.     lda UserPathPtr
  3251.     sta <Temp
  3252.     lda UserPathPtr+2
  3253.     sta <Temp+2
  3254.     
  3255. ; To put an index-like value in Y, get the length and add 2 to it.
  3256.  
  3257.     lda [<Temp]
  3258.     inc a
  3259.     inc a
  3260.     tay
  3261.     
  3262. ; That's all the AppleShare-specific stuff; fall through to a common construction
  3263. ; routine
  3264.  
  3265.     bra @Common
  3266.  
  3267. ;
  3268. ; Now, for a local pathname:
  3269. ; Get the length of the pathname, add 2-1 to account for the length word, and start
  3270. ; indexing backwards looking for a colon (:)
  3271. ;
  3272.  
  3273. @DoLocalPath    lda [<Temp]
  3274.     inc a
  3275.     tay
  3276.     shortm    ; 8-bit accumulator
  3277.     
  3278. @ColonLoop    lda [<Temp],y
  3279.     cmp #':'
  3280.     beq @FoundTheColon    ; (no remarks about anatomy, please)
  3281.     dey
  3282.     bra @ColonLoop    ; there has to be at least one colon
  3283.     
  3284. @FoundTheColon    longm
  3285.     
  3286. ;
  3287. ; OK, now we have the colon place.  Now think carefully about this -- I got this wrong
  3288. ; bunches of times.  GSBug is your friend.
  3289. ; Because of the length word at the beginning of the LGetPathname2 result, the _length_
  3290. ; of the result MINUS THE FILENAME is two more than what's in Y.  So, to get the length
  3291. ; of the handle to allocate for the preferences path, we subtract two from Y, then add
  3292. ; the length of the preferences file name and two bytes for the length buffer.  That
  3293. ; simplifies to adding the length of the preferences file to Y and we've got it.
  3294.  
  3295.  
  3296. @Common    phy    ; save this for a second
  3297.     clc
  3298.     lda PrefsFileName
  3299.     and #$00FF
  3300.     adc 1,s    ; add with saved index
  3301.     sta TempLength    ; keep this for later
  3302.     
  3303.     pha
  3304.     pha    ; space for result
  3305.     pea 0
  3306.     pha    ; size
  3307.     pushword IRUserID
  3308.     pushword #$4008    ; fixed, no special memory
  3309.     lda #0
  3310.     pha
  3311.     pha
  3312.     _NewHandle
  3313.     pulllong <TempAlso
  3314.     pha    ; save error code
  3315.     lda [<TempAlso]
  3316.     tax
  3317.     ldy #2
  3318.     lda [<TempAlso],y
  3319.     sta <TempAlso+2
  3320.     stx <TempAlso
  3321.     pla    ; restore error code
  3322.     ply    ; restore index into y
  3323.     bcc @2
  3324.     brl PrefsPathError    ; thought I'd forgotten error checking, didn'cha?
  3325.     
  3326. ;
  3327. ; Now, TempAlso points to memory we want to move that amount of bytes to -- from [Temp]+2
  3328. ; and ranging for index - 2, moved to [TempAlso] + 2.
  3329. ;
  3330.  
  3331. @2    phy    ; save the index again
  3332.     
  3333.     clc
  3334.     lda <Temp
  3335.     adc #2
  3336.     tax
  3337.     lda <Temp+2
  3338.     adc #0
  3339.     pha
  3340.     phx    ; source
  3341.     
  3342.     clc
  3343.     lda <TempAlso
  3344.     adc #2
  3345.     tax
  3346.     lda <TempAlso+2
  3347.     adc #0
  3348.     pha
  3349.     phx    ; destination
  3350.     
  3351.     tya    ; index
  3352.     dec a
  3353.     dec a
  3354.     pea $0000
  3355.     pha    ; count
  3356.     _BlockMove
  3357.     
  3358.     ply    ; restore the index
  3359.     
  3360. ;
  3361. ; Now (and I was told there'd be no math, <sigh>) add the index (which, remember, includes
  3362. ; the length word) to <TempAlso to get the address of the place to move "IR.Preferences".
  3363. ;
  3364.  
  3365.     tya
  3366.     clc
  3367.     adc <TempAlso
  3368.     sta <Temp    ; we're done with LGetPathname2 now
  3369.     lda #0
  3370.     adc <TempAlso+2
  3371.     sta <Temp+2
  3372.     
  3373.     pushlong #PrefsFileName+1 ; don't forget to not move the length byte!
  3374.     pei <Temp+2
  3375.     pei <Temp
  3376.     lda PrefsFileName
  3377.     and #$00FF
  3378.     pea 0000
  3379.     pha    ; count
  3380.     _BlockMove
  3381.     
  3382. ;
  3383. ; Now, fix the length word and everything is OK.  Subtract 2 because it includes
  3384. ; the length word.
  3385.  
  3386.     lda TempLength
  3387.     dec a
  3388.     dec a
  3389.     sta [<TempAlso]
  3390.     
  3391. ;
  3392. ; Finally, Temp contains the address of our GS/OS pathname to the preferences file.  Move
  3393. ; it into permanent storage and propagate it throughout the parameter blocks.
  3394. ;
  3395.  
  3396.     lda <TempAlso
  3397.     sta PrefsPathPtr
  3398.     sta CreatePath
  3399.     sta OpenPath
  3400.     lda <TempAlso+2
  3401.     sta PrefsPathPtr+2
  3402.     sta CreatePath+2
  3403.     sta OpenPath+2
  3404.     
  3405. GotPrefsPath    lda #0
  3406.     clc
  3407. PrefsPathError    rts
  3408.  
  3409. TempLength    dc.w 0    ; temporary length storage
  3410. LocalFlag    dc.w 0    ; flag to see if this is forced to local
  3411.  
  3412.     EndP
  3413.  
  3414.     EJECT
  3415. *******************************************************************************
  3416. *
  3417. CheckFileAuxType    PROCNAME
  3418. *
  3419. * Description:    Takes a filetype in A and auxtype in X (low) and Y (high)
  3420. *    and sees if IR can install this.  Returns carry clear if
  3421. *    we can and carry set if we can't.  Also returns user ID
  3422. *    range for this thing we're trying to load.
  3423. *
  3424. *
  3425. * Inputs:    Filetype in A, auxtype in X (low) and Y (high)
  3426. *
  3427. * Outputs:    Carry clear if IR does anything.  User ID to pass to
  3428. *    InitialLoad2 in A, or zero if carry is set.
  3429. *
  3430. * External Refs:
  3431.     WITH IRData
  3432. *    uses FileType and AuxType on direct page
  3433. *
  3434. * Entry Points:
  3435. *
  3436. *******************************************************************************
  3437.  
  3438. ;
  3439. ; First, see if the auxtype high word is zero -- if not, we don't do this
  3440. ; type.
  3441. ;
  3442.  
  3443.     cpy #0
  3444.     bne @NotOurType
  3445.     
  3446. ;
  3447. ; OK, so store the types on direct page and begin checking the table.
  3448. ;
  3449.  
  3450.     sta Filetype
  3451.     stx Auxtype
  3452.     
  3453.  
  3454.     ldx #0    ; initialize this index
  3455.     ldy FTTableCount    ; this one too
  3456.     
  3457. @FileTypeLoop    lda fileTypeTable,x    ; the filetype
  3458.     cmp <FileType
  3459.     bne @NextTypeEntry
  3460.     
  3461.     lda <Auxtype
  3462.     and fileTypeTable+2,x ; the auxtype mask
  3463.     cmp fileTypeTable+4,x ; the desired auxtype
  3464.     beq @GotIt    ; we found our type
  3465.     
  3466. @NextTypeEntry    dey
  3467.     beq @NotOurType    ; not ours
  3468.     clc
  3469.     txa
  3470.     adc #sizeOfFTEntry
  3471.     tax    ; next entry
  3472.     bra @FileTypeLoop
  3473.     
  3474. @GotIt    lda fileTypeTable+6,x ; the user ID range
  3475.     clc
  3476.     rts
  3477.     
  3478. @NotOurType    lda #0
  3479.     sec
  3480.     rts
  3481.  
  3482.     EndP
  3483.  
  3484.     EJECT
  3485. *******************************************************************************
  3486. *
  3487. IRDoesPreferences    PROCNAME
  3488. *
  3489. * Description:    Test/do the IR preferences dialog box.
  3490. *
  3491. *
  3492. * Inputs:    None
  3493. *
  3494. * Outputs:    None
  3495. *
  3496. * External Refs:
  3497.     with IRData
  3498.     import GetPrefsFromControls
  3499.     import SetControlsFromPrefs
  3500.     import SetPrefs
  3501.     import GiveMeMyFork
  3502. *
  3503. * Entry Points:
  3504. *
  3505. *******************************************************************************
  3506.  
  3507. RectPtr    equ Temp
  3508. PrefsPtr    equ TempAlso
  3509. AlertPtr    equ DIBPtr    ; this should be safe in here
  3510.  
  3511. ;
  3512. ; Zeroth (before first but written later), do nothing if the Window
  3513. ; Manager isn't active.
  3514. ;
  3515.  
  3516.     pea $0000
  3517.     _WindStatus
  3518.     pla
  3519.     bne @First
  3520.     brl Out    ; do nothing if no Window Manager
  3521.  
  3522.  
  3523. ;
  3524. ; First, get our resource file ready and get the TwoRects resource.
  3525. ;
  3526.  
  3527. @First    jsr GiveMeMyFork
  3528.     
  3529.     pha
  3530.     pha    ; space for result
  3531.     pushword #rTwoRects ; type
  3532.     pushlong #WindowRects ; ID
  3533.     _LoadResource
  3534.     pulllong <RectPtr
  3535.     bcc @NoError0
  3536.     brl Out    ; no error reporting, but get out of here
  3537.     
  3538. @NoError0    lda [<RectPtr]
  3539.     tax
  3540.     ldy #2
  3541.     lda [<RectPtr],y
  3542.     sta <RectPtr+2
  3543.     stx <RectPtr    ; RectPtr now points to rectangles
  3544.     
  3545. ;
  3546. ; Now, get our AlertString resource and window resource for adjusting their
  3547. ; rectangles
  3548. ;
  3549.  
  3550.     pha
  3551.     pha    ; space for result
  3552.     pushword #rAlertString
  3553.     pushlong #irAboutAlert
  3554.     _LoadResource
  3555.     pulllong <AlertPtr
  3556.     bcc @NoError1
  3557.     brl Out    ; no error reporting, but get out of here
  3558.     
  3559. @NoError1    lda [<AlertPtr]
  3560.     tax
  3561.     ldy #2
  3562.     lda [<AlertPtr],y
  3563.     sta <AlertPtr+2
  3564.     inx
  3565.     stx <AlertPtr    ; AlertPtr now points to alert rectangle
  3566.         ; we can do that because the alert resource
  3567.         ; is marked noBankCross.
  3568.     
  3569.     pha
  3570.     pha    ; space for result
  3571.     pushword #rWindParam1
  3572.     pushlong #Preferences_Window
  3573.     _LoadResource
  3574.     pulllong <PrefsPtr
  3575.     bcc @NoError2
  3576.     brl Out    ; no error reporting, but get out of here
  3577.     
  3578. @NoError2    lda [<PrefsPtr]
  3579.     tax
  3580.     ldy #2
  3581.     lda [<PrefsPtr],y
  3582.     sta <PrefsPtr+2
  3583.     stx <PrefsPtr    ; PrefsPtr now points to preferences window
  3584.     clc
  3585.     lda #owPosition
  3586.     adc <PrefsPtr
  3587.     sta <PrefsPtr    ; PrefsPtr now points to window rectangle
  3588.         ; we can do that because the alert resource
  3589.         ; is marked noBankCross.
  3590.     
  3591. ;
  3592. ; Then adjust the rectangles for whatever mode we're in
  3593. ;
  3594.  
  3595. @RectFutz    pha
  3596.     _GetMasterSCB
  3597.     pla
  3598.     and #$0080    ; mask out all but the 320/640 bit
  3599.     beq @MoveRect    ; <RectPtr already points to 320 rectangle
  3600. @Do640    lda #8
  3601.     clc
  3602.     adc <RectPtr
  3603.     sta <RectPtr
  3604.     lda #0
  3605.     adc <RectPtr+2
  3606.     sta <RectPtr+2    ; RectPtr := RectPtr + 8 --> points to 640 rect
  3607. @MoveRect    ldy #6
  3608. @MoveRectLoop    lda [RectPtr],y
  3609.     sta [PrefsPtr],y
  3610.     sta [AlertPtr],y
  3611.     dey
  3612.     dey
  3613.     bpl @MoveRectLoop
  3614.  
  3615. ;
  3616. ; Then, release the rectangle resource and create the window
  3617. ;
  3618.  
  3619.     pushword #$FFFF    ; negative == kill it now
  3620.     pushword #rTwoRects
  3621.     pushlong #WindowRects
  3622.     _ReleaseResource
  3623.  
  3624.     lda #0
  3625.     pha
  3626.     pha    ; space for result
  3627.     pha
  3628.     pha    ; no replacement title
  3629.     pha
  3630.     pha    ; no refcon
  3631.     pha
  3632.     pha    ; no replacement content draw routine
  3633.     pha
  3634.     pha    ; standard defproc
  3635.     pushword #2    ; reference is by resource
  3636.     
  3637. ;
  3638. ; By the way, we can do that (^^^) because as long as the resource is loaded and
  3639. ; non-purgeable, the Resource Manager will return the previous handle.  We
  3640. ; must _not_ mark it as "changed" or the Resource Manager will try to
  3641. ; write it to disk, and that would be Bad.
  3642. ;
  3643.  
  3644.     pushlong #Preferences_Window ; window reference
  3645.     pea $800E    ; template like rWindParam1
  3646.     _NewWindow2
  3647.     pulllong <PrefsWindPtr
  3648.     
  3649. @MakeCtlsRight    lda LocalPrefs
  3650.     jsr SetControlsFromPrefs
  3651.     
  3652. ;
  3653. ; Before showing the window, change the preferences control to point to
  3654. ; our version string (left over from IRStartsUp).
  3655. ;
  3656.  
  3657.     pha
  3658.     pha    ; space for result
  3659.     pei <PrefsWindPtr+2
  3660.     pei <PrefsWindPtr
  3661.     pushlong #VersionID
  3662.     _GetCtlHandleFromID
  3663.     pulllong <Temp    ; save for a bit
  3664.     
  3665.     pushlong #IRBootVersion+1
  3666.     pei <Temp+2
  3667.     pei <Temp
  3668.     _SetCtlTitle    ; no length word
  3669.     
  3670.     pushword VersionLength
  3671.     pei <Temp+2
  3672.     pei <Temp
  3673.     _SetCtlValue    ; value == length of static text
  3674.  
  3675.     pei <PrefsWindPtr+2
  3676.     pei <PrefsWindPtr
  3677.     _ShowWindow
  3678.  
  3679. @ModalWindLoop    lda #0
  3680.     pha
  3681.     pha    ; space for result
  3682.     pushlong #MyTaskRec    ; task record
  3683.     lda #0
  3684.     pha
  3685.     pha    ; standard update proc
  3686.     pushlong #$80000000    ; standard event hook, leaves $0000 in A
  3687.     pha
  3688.     pha    ; standard beep procedure
  3689.     pea %1000000000000000 ; flags
  3690.     _DoModalWindow
  3691.     pulllong <Temp    ; the ID of the control hit
  3692.     
  3693. ;
  3694. ; See if we hit a dismissing control or the version number.  We only test the low
  3695. ; word of each ID because we restrict control IDs to less than $10000.
  3696. ;
  3697.  
  3698.     lda <Temp
  3699.     cmp #AcceptID
  3700.     bne @notAccept
  3701. @isAccept    jsr GetPrefsFromControls
  3702.     sta LocalPrefs
  3703.     jsr SetPrefs
  3704.     brl ClosePrefsWindow
  3705.     
  3706. @notAccept    ;lda <Temp
  3707.     cmp #CancelID
  3708.     bne @notCancel
  3709. @isCancel    brl ClosePrefsWindow
  3710.  
  3711. @notCancel    ;lda <Temp
  3712.     cmp #SaveID
  3713.     bne @notSave
  3714. @isSave    jsr GetPrefsFromControls
  3715.     sta LocalPrefs
  3716.     ora #IrDoDiskPrefs
  3717.     jsr SetPrefs
  3718.     brl ClosePrefsWindow
  3719.     
  3720. @notSave    ;lda <Temp
  3721.     cmp #VersionID
  3722.     bne @notVersion
  3723. @isVersion    lda #0
  3724.     pha    ; space for result
  3725.     pea $02AC    ; string is resource, no sub strings,
  3726.         ; use new button placement, no sound,
  3727.         ; ignore icon rect when centering text,
  3728.         ; use icon resource instead of inline icon,
  3729.         ; release resource to purge level 3 instead
  3730.         ; of disposing it.
  3731.     pha
  3732.     pha    ; no substitution array
  3733.     pushlong #irAboutAlert ; Reference to alert string
  3734.     _AlertWindow
  3735.     pla
  3736.  
  3737. @notVersion    brl @ModalWindLoop    ; do it over again
  3738.  
  3739. ClosePrefsWindow    pei <PrefsWindPtr+2
  3740.     pei <PrefsWindPtr
  3741.     _CloseWindow
  3742.     
  3743. ;
  3744. ; Since the AlertString and window resources are locked, we need to manually release 
  3745. ; them to get them disposed.
  3746. ;
  3747.  
  3748. Out    pushword #$FFFF
  3749.     pushword #rAlertString
  3750.     pushlong #irAboutAlert
  3751.     _ReleaseResource
  3752.     
  3753.     pushword #$FFFF
  3754.     pushword #rWindParam1
  3755.     pushlong #Preferences_Window
  3756.     _ReleaseResource
  3757.     
  3758.     lda #0
  3759.     clc
  3760.     rts
  3761.     
  3762. LocalPrefs    dc.w irDefaultPrefs
  3763.     EndP
  3764.  
  3765.     EJECT
  3766. *******************************************************************************
  3767. *
  3768. SetPrefs    PROCNAME
  3769. *
  3770. * Description:    I have a request procedure to set the preferences, but I
  3771. *    need to call a regular subroutine.  So this is glue that
  3772. *     takes preferences in A and calls IRSetsPreferences.
  3773. *    This glue is not reentrant.
  3774. *
  3775. *
  3776. * Inputs:    Preferences in A.
  3777. *
  3778. * Outputs:    Errors in A/carry.
  3779. *
  3780. * External Refs:    
  3781.     with IRData
  3782. *
  3783. * Entry Points:    None.
  3784. *
  3785. *******************************************************************************
  3786.  
  3787.     tax    ; save preferences in X
  3788.     pushword #askIRSetPrefs
  3789.     pushword #SendToName+stopAfterOne
  3790.     pushlong #IRString
  3791.     pea 0000    ; high word
  3792.     phx    ; preferences
  3793.     pushlong #PrefsDataOut
  3794.     _SendRequest
  3795.     
  3796.     lda PrefsResult
  3797.     cmp #1
  3798.     rts
  3799.  
  3800. PrefsDataOut    dc.w 0    ; recvCount
  3801. PrefsResult    dc.w 0
  3802.  
  3803.     EndP
  3804.     
  3805.     EJECT
  3806. *******************************************************************************
  3807. *
  3808. GetPrefsFromControls PROCNAME
  3809. *
  3810. * Description:    Takes the controls in the prefs window and returns an IR
  3811. *    preferences word with their contents, as we use them.
  3812. *
  3813. *
  3814. * Inputs:    PrefsWindPtr == pointer to the preferences window
  3815. *
  3816. * Outputs:    Prefs word in accumulator
  3817. *
  3818. * External Refs:
  3819.     import ValueFromID
  3820. *
  3821. * Entry Points:
  3822. *
  3823. *******************************************************************************
  3824.  
  3825.     stz BuildPrefs    ; zero out our building prefs word
  3826.  
  3827. ;
  3828. ; Set the irNoDuplicates bit if the "Always kill old file" radio button is selected
  3829. ;
  3830.     ldy #AlwaysKillOldID
  3831.     ldx #AlwaysKillOldID>>16
  3832.     jsr ValueFromID
  3833.     beq @DuplicatesOK
  3834.     lda #irNoDuplicates+irKillDuplicates
  3835.     tsb BuildPrefs
  3836.     bra @DoneDuplicates
  3837.     
  3838. @DuplicatesOK    ldy #TryKillOldID
  3839.     ldx #TryKillOldID>>16
  3840.     jsr ValueFromID
  3841.     beq @DoneDuplicates    ; taken if "always install new" is chosen
  3842.     lda #irNoDuplicates
  3843.     tsb BuildPrefs
  3844.     
  3845. @DoneDuplicates        ; the word is already zeroed.
  3846.  
  3847. ;
  3848. ; Set the irDontOpenNDAs bit if the "Open new NDAs" box is unchecked.
  3849. ;
  3850.  
  3851.     ldy #OpenNewNDAID
  3852.     ldx #OpenNewNDAID>>16
  3853.     jsr ValueFromID
  3854.     bne @GotNDAs
  3855.     lda #irDontOpenNDAs
  3856.     tsb BuildPrefs
  3857.  
  3858. @GotNDAs
  3859.  
  3860. ;
  3861. ; Set the irKillFinderExts bit if the "Install permanently" check box is NOT checked.
  3862. ;
  3863.  
  3864.     ldy #FinderExtID
  3865.     ldx #FinderExtID>>16
  3866.     jsr ValueFromID
  3867.     bne @NoKillFEs
  3868.     lda #irKillFinderExts
  3869.     tsb BuildPrefs
  3870.     
  3871. @NoKillFEs    
  3872.     
  3873. ;
  3874. ; Set the irCopyExistNDAs bit if the "Open NDAs" check box is clear.
  3875. ;
  3876.  
  3877.     ldy #CopyExistNDAsID
  3878.     ldx #CopyExistNDAsID>>16
  3879.     jsr ValueFromID
  3880.     bne @noOpenNDAs
  3881.     lda #irCopyExistNDAs
  3882.     tsb BuildPrefs
  3883.     
  3884. @noOpenNDAs
  3885.  
  3886. ;
  3887. ; Set the irWaitOpenFailed bit if the "Give others..." check box is set.
  3888. ;
  3889.  
  3890.     ldy #DoBeforeOpenID
  3891.     ldx #DoBeforeOpenID>>16
  3892.     jsr ValueFromID
  3893.     beq @noWaitOpenFailed ; don't set the bit if the box was empty
  3894.     lda #irWaitOpenFailed
  3895.     tsb BuildPrefs
  3896.  
  3897. ;
  3898. ; Set the irIgnoreProblems bit if "Alert me ..." check box is clear.
  3899. ;
  3900.  
  3901. @noWaitOpenFailed    ldy #DoAlertsID
  3902.     ldx #DoAlertsID>>16
  3903.     jsr ValueFromID
  3904.     bne @dontIgnoreProblems
  3905.     lda #irIgnoreProblems
  3906.     tsb BuildPrefs
  3907.  
  3908. @dontIgnoreProblems    lda BuildPrefs
  3909.     rts    ; that's it!
  3910.     
  3911. BuildPrefs    dc.w 0    ; for temporary storage    
  3912.     
  3913.     EndP
  3914.     
  3915.     EJECT
  3916. *******************************************************************************
  3917. *
  3918. SetControlsFromPrefs PROCNAME
  3919. *
  3920. * Description:    Takes a prefs word in A and initializes the controls in
  3921. *    the prefs window to the indicated states.
  3922. *
  3923. *
  3924. * Inputs:    Prefs word in A, PrefsWindPtr == pointer to prefs window
  3925. *
  3926. * Outputs:    None
  3927. *
  3928. * External Refs:
  3929.     import SetValueFromID
  3930. *
  3931. * Entry Points:
  3932. *
  3933. *******************************************************************************
  3934.  
  3935.     sta BuildPrefs    ; keep this
  3936.  
  3937. ;
  3938. ; Select the "Install a new copy" radio button if irNoDuplicates is clear
  3939. ;
  3940.     
  3941.     and #irNoDuplicates
  3942.     bne @MoreDuplicates
  3943.     lda #1
  3944.     ldy #InstallNewID
  3945.     ldx #InstallNewID>>16
  3946.     jsr SetValueFromID
  3947.     bra @DoneDuplicates
  3948.     
  3949. ;
  3950. ; So, irNoDuplicates is set -- now set "Always remove old one" if irKillDuplicates is set.
  3951. ;
  3952.  
  3953. @MoreDuplicates    lda BuildPrefs
  3954.     and #irKillDuplicates
  3955.     beq @SetTryButton
  3956.     lda #1
  3957.     ldy #AlwaysKillOldID
  3958.     ldx #AlwaysKillOldID>>16
  3959.     jsr SetValueFromID
  3960.     bra @DoneDuplicates
  3961.     
  3962. @SetTryButton    lda #1
  3963.     ldy #TryKillOldID
  3964.     ldx #TryKillOldID>>16
  3965.     jsr SetValueFromID
  3966.     
  3967. @DoneDuplicates
  3968.  
  3969. ;
  3970. ; Now for the checkboxes
  3971. ; Set the "Open new NDAs" box if irDontOpenNDAs is clear.
  3972. ;
  3973.  
  3974.     lda BuildPrefs
  3975.     and #irDontOpenNDAs
  3976.     eor #irDontOpenNDAs
  3977. ;
  3978. ; That's a nifty trick, by the way -- if the bit was set, the eor makes the whole word
  3979. ; zero, which will be an unchecked value.  If the bit was clear, the eor makes it set,
  3980. ; which makes A hold a non-zero value that will check the check box.
  3981. ;
  3982.     ldy #OpenNewNDAID
  3983.     ldx #OpenNewNDAID>>16
  3984.     jsr SetValueFromID
  3985.     
  3986. ;
  3987. ; Next, set the "Install FEs permanently" if irKillFinderExts is clear
  3988. ;
  3989.  
  3990.     lda BuildPrefs
  3991.     and #irKillFinderExts
  3992.     eor #irKillFinderExts ; see above, same trick
  3993.     ldy #FinderExtID
  3994.     ldx #FinderExtID>>16
  3995.     jsr SetValueFromID
  3996.     
  3997. ;
  3998. ; Next, check the "Open existing NDAs" box if irCopyExistNDAs is clear.
  3999. ;
  4000.  
  4001.     lda BuildPrefs
  4002.     and #irCopyExistNDAs
  4003.     eor #irCopyExistNDAs
  4004.     ldy #CopyExistNDAsID
  4005.     ldx #CopyExistNDAsID>>16
  4006.     jsr SetValueFromID
  4007.  
  4008. ;
  4009. ; Check the "Alert me..." box if irIgnoreProblems is clear.
  4010. ;
  4011.  
  4012.     lda BuildPrefs
  4013.     and #irIgnoreProblems
  4014.     eor #irIgnoreProblems
  4015.     ldy #DoAlertsID
  4016.     ldx #DoAlertsID>>16
  4017.     jsr SetValueFromID
  4018. ;
  4019. ; And check the "Give others..." check box if irWaitOpenFailed is set.
  4020. ;
  4021.  
  4022.     lda BuildPrefs
  4023.     and #irWaitOpenFailed
  4024.     ldy #DoBeforeOpenID
  4025.     ldx #DoBeforeOpenID>>16
  4026.     jsr SetValueFromID
  4027.  
  4028.     rts    ; that's it!
  4029.     
  4030. BuildPrefs    dc.w 0    ; temporary storage    
  4031.  
  4032.     EndP
  4033.  
  4034.     EJECT
  4035. *******************************************************************************
  4036. *
  4037. ValueFromID    PROCNAME
  4038. *
  4039. * Description:    Gets the control value from a control ID.
  4040. *
  4041. *
  4042. * Inputs:    Control ID (high/low) in X/Y
  4043. *
  4044. * Outputs:    Control value in the accumulator
  4045. *
  4046. * External Refs:
  4047. *
  4048. * Entry Points:
  4049. *
  4050. *******************************************************************************
  4051.  
  4052.     pha    ; space for resulting control value
  4053.     pha
  4054.     pha    ; space for control handle
  4055.     pei <PrefsWindPtr+2
  4056.     pei <PrefsWindPtr    ; window pointer
  4057.     phx    ; high word of ID
  4058.     phy    ; low word of ID
  4059.     _GetCtlHandleFromID
  4060.     _GetCtlValue
  4061.     pla    ; got the control value in A
  4062.     rts
  4063.     
  4064.     EndP
  4065.  
  4066.     EJECT
  4067. *******************************************************************************
  4068. *
  4069. SetValueFromID    PROCNAME
  4070. *
  4071. * Description:    Takes a control value in A and a control ID in X/Y
  4072. *    (high/low) and sets that control's value.
  4073. *
  4074. *
  4075. * Inputs:    Control value in A, ID in X/Y
  4076. *
  4077. * Outputs:    None
  4078. *
  4079. * External Refs:
  4080. *
  4081. * Entry Points:
  4082. *
  4083. *******************************************************************************
  4084.  
  4085.     pha    ; save the value 
  4086.     pha
  4087.     pha    ; space for control handle
  4088.     pei <PrefsWindPtr+2
  4089.     pei <PrefsWindPtr
  4090.     phx
  4091.     phy    ; the control ID
  4092.     _GetCtlHandleFromID
  4093.     _SetCtlValue
  4094.     rts
  4095.     
  4096.     EndP
  4097.  
  4098.     EJECT
  4099. *******************************************************************************
  4100. *
  4101. AddIDToQueue    PROCNAME
  4102. *
  4103. * Description:    Our "queues" are a word count of how many user IDs are in
  4104. *    them, a word count of how many user IDs the current
  4105. *    handle size will hold, and a lot of user IDs.  If the
  4106. *    handle is zero, there is no handle and we allocate a
  4107. *    new one.  If the handle will hold more user IDs, we just
  4108. *    add the new one.  If it won't, we grow it by a fixed
  4109. *    amount and then add the new one.
  4110. *
  4111. *
  4112. * Inputs:    User ID to add in A, Queue number in X.
  4113. *
  4114. * Outputs:    None.  No errors because if we can't grow a handle
  4115. *    by a measly 40 bytes or so, the system's already in
  4116. *    serious trouble.
  4117. *
  4118. * External Refs:
  4119.     with IRData
  4120.     IMPORT GetQueuePtr
  4121. *
  4122. * Entry Points:
  4123. *
  4124. *******************************************************************************
  4125.  
  4126. ;
  4127. ; A couple of private, helpfully documenting equates
  4128. ;
  4129.  
  4130. UserID    equ Temp
  4131. QueueNum    equ Temp+2
  4132. QueuePtr    equ TempAlso
  4133.  
  4134.     tay    ; save this for now
  4135.     
  4136.     pushlong Temp
  4137.     pushlong TempAlso    ; save both these so we can use them
  4138.  
  4139.     sty <UserID
  4140.     stx <QueueNum
  4141.     
  4142.     jsr GetQueuePtr    ; set up the pointer to this Queue
  4143.     
  4144. ;
  4145. ; Now, see if we can fit one more user ID into this Queue.
  4146. ;
  4147.  
  4148.     ldy #2
  4149.     lda [<QueuePtr],y    ; how many entries can this hold?
  4150.     sec
  4151.     sbc [<QueuePtr]
  4152.     bne @ItWillFit
  4153.     
  4154.     lda [QueuePtr],y    ; entries this one can hold
  4155.     asl a    ; each entry is two bytes
  4156.     clc
  4157.     adc #4    ; now A contains the size of this handle
  4158.     adc #startIDCount
  4159.     pea 0
  4160.     pha    ; size
  4161.     pha
  4162.     pha    ; space for result
  4163.     pei <QueuePtr+2
  4164.     pei <QueuePtr
  4165.     _FindHandle
  4166.     _SetHandleSize
  4167.     
  4168.     ldx <QueueNum
  4169.     jsr GetQueuePtr    ; redereference and start over
  4170.     
  4171.     clc
  4172.     lda [<QueuePtr]
  4173.     adc #startIDCount
  4174.     sta [<QueuePtr]    ; add count of new ID capability to queue
  4175.     
  4176. ;
  4177. ; At this point, QueuePtr contains a pointer to a queue that will definitely hold
  4178. ; the user ID we want to add to it.
  4179. ;
  4180.     
  4181. @ItWillFit    lda [<QueuePtr]    ; how many entries are here?
  4182.  
  4183. ;
  4184. ; Since the counts are one-based, we  have to increment the entry count by
  4185. ; two so that when we double it, it includes the four bytes of overhead at the
  4186. ; beginning.
  4187. ;
  4188.  
  4189.     inc a
  4190.     inc a
  4191.     asl a    ; double it
  4192.     tay
  4193.     lda <UserID
  4194.     sta [<QueuePtr],y
  4195.     lda [<QueuePtr]
  4196.     inc a
  4197.     sta [<QueuePtr]
  4198.     
  4199.     pulllong <TempAlso
  4200.     pulllong <Temp
  4201.     
  4202.     rts
  4203.  
  4204.     EndP        
  4205.  
  4206.     EJECT
  4207. *******************************************************************************
  4208. *
  4209. GetQueuePtr    PROCNAME
  4210. *
  4211. * Description:    GetQueuePtr takes a queue number in X and returns the
  4212. *    pointer to that queue in TempAlso.
  4213. *
  4214. * Inputs:    Queue number in X.
  4215. *
  4216. * Outputs:    Queue pointer in QueuePtr (TempAlso)
  4217. *
  4218. * External Refs:
  4219.     with IRData
  4220. *
  4221. * Entry Points:
  4222. *
  4223. *******************************************************************************
  4224.     
  4225. QueuePtr    equ TempAlso
  4226.  
  4227.     txa
  4228.     asl a
  4229.     asl a    ; multiply by four for indexing
  4230.     tay
  4231.     
  4232.     lda QueueTable,y
  4233.     ora QueueTable+2,y
  4234.     bne @GotHandle
  4235.     
  4236. @NeedHandle    phy    ; save the index
  4237.     pha
  4238.     pha    ; space for result
  4239.     pushlong #startIDCount*2+4
  4240.     pushword IRUserID
  4241.     lda #0
  4242.     pha    ; unlocked, totally open
  4243.     pha
  4244.     pha    ; in any bank, etc.
  4245.     _NewHandle
  4246.     lda 5,s    ; the saved index
  4247.     tay
  4248.     pla    ; low word of handle
  4249.     sta QueueTable,y    ; into the table
  4250.     tax
  4251.     pla
  4252.     sta QueueTable+2,y    ; the low word of the handle
  4253.     sta <QueuePtr+2
  4254.     stx <QueuePtr
  4255.     ply    ; balance the stack
  4256.     
  4257.     lda [<QueuePtr]
  4258.     tax
  4259.     ldy #2
  4260.     lda [<QueuePtr],y
  4261.     sta <QueuePtr+2
  4262.     stx <QueuePtr    ; now QueuePtr points to the queue
  4263.     
  4264.     ldy #2
  4265.     lda #startIDCount
  4266.     sta [<QueuePtr],y    ; how many this handle can hold
  4267.     lda #0
  4268.     sta [<QueuePtr]    ; holds none right now
  4269.     
  4270.     bra @GotQueuePtr
  4271.     
  4272. @GotHandle    lda QueueTable,y
  4273.     tax
  4274.     lda QueueTable+2,y
  4275.     sta <QueuePtr+2
  4276.     stx <QueuePtr
  4277.     
  4278.     lda [<QueuePtr]
  4279.     tax
  4280.     ldy #2
  4281.     lda [<QueuePtr],y
  4282.     sta <QueuePtr+2
  4283.     stx <QueuePtr    ; now QueuePtr points to the queue
  4284.     
  4285. @GotQueuePtr    rts
  4286.     
  4287.     EndP
  4288.  
  4289.     EJECT
  4290. *******************************************************************************
  4291. *
  4292. GetQueueHandle    PROCNAME
  4293. *
  4294. * Description:    GetQueueHandle takes a queue number in X and returns the
  4295. *    handle to that queue in TempAlso.  It does _NOT_ allocate
  4296. *    a new handle if one for that queue does not exist.
  4297. *
  4298. *    If the high bit of X is set, the queue handle is locked
  4299. *    before it's returned.
  4300. *
  4301. * Inputs:    Queue number in X.
  4302. *
  4303. * Outputs:    Queue handle in QueuePtr (TempAlso)
  4304. *
  4305. * External Refs:
  4306.     with IRData
  4307. *
  4308. * Entry Points:
  4309. *
  4310. *******************************************************************************
  4311.     
  4312. QueuePtr    equ TempAlso
  4313.  
  4314.     phx    ; save this
  4315.     
  4316.     txa
  4317.     asl a
  4318.     asl a    ; multiply by four for indexing
  4319.     tay
  4320.     
  4321.     
  4322. @ItsHandle    lda QueueTable,y    ; low word of handle for the queue
  4323.     tax
  4324.     lda QueueTable+2,y    ; high word of handle
  4325.     sta <QueuePtr+2
  4326.     stx <QueuePtr
  4327.  
  4328.     pla    ; the queue number
  4329.     bpl @Done    ; if high bit clear, we're done
  4330.     
  4331.     lda <QueuePtr
  4332.     ora <QueuePtr+2
  4333.     beq @Done    ; we're done if it's NIL, also
  4334.     
  4335.     ldy #4
  4336.     lda [<QueuePtr],y
  4337.     ora #$8000    ; set the locked bit
  4338.     sta [<QueuePtr],y
  4339.     
  4340. @Done    lda #0
  4341.     clc
  4342.     rts
  4343.     
  4344.     EJECT
  4345. *******************************************************************************
  4346. *
  4347. KillThisQueue    PROCNAME
  4348. *
  4349. * Description:    Kills the handle for the queue number in X and stores
  4350. *    zeroes in the queue table for that queue's handle.
  4351. *
  4352. *
  4353. * Inputs:    Queue number in X.
  4354. *
  4355. * Outputs:    None
  4356. *
  4357. * External Refs:
  4358.     with IRData
  4359. *
  4360. * Entry Points:
  4361. *
  4362. *******************************************************************************
  4363.  
  4364. QueuePtr    equ TempAlso
  4365.  
  4366.     pei <QueuePtr+2
  4367.     pei <QueuePtr    ; save these real quick
  4368.     
  4369.     txa
  4370.     asl a
  4371.     asl a    ; multiply by four for indexing
  4372.     tax
  4373.     
  4374. @ItsHandle    phx    ; I need this shortly
  4375.     lda QueueTable,x    ; low word of handle for the queue
  4376.     tay
  4377.     lda QueueTable+2,x    ; high word of handle
  4378.     pha
  4379.     phy    ; handle on stack
  4380.     _DisposeHandle    ; get rid of it
  4381.     plx    ; get this index back
  4382.     
  4383.     stz QueueTable,x
  4384.     stz QueueTable+2,x
  4385.     
  4386.     pulllong <QueuePtr    ; restore this
  4387.     
  4388.     lda #0
  4389.     clc
  4390.     rts
  4391.     
  4392.     
  4393.     EJECT
  4394. *******************************************************************************
  4395. *
  4396. OpenNDAByUserID    PROCNAME
  4397. *
  4398. * Description:    Takes a user ID in A and opens the NDA window for that
  4399. *    user ID.  If the window is already open, it selects it
  4400. *    instead.
  4401. *
  4402. *
  4403. * Inputs:    User ID in A.
  4404. *
  4405. * Outputs:    None.  Assumes this is an NDA ID; takes no action if not.
  4406. *
  4407. * External Refs:
  4408. *
  4409. * Entry Points:
  4410.     ENTRY UserIDToDAID
  4411. *
  4412. *******************************************************************************
  4413.  
  4414.     ldx #0    ; we want NDA ID's
  4415.     jsr UserIDToDAID
  4416.     sta DANum    ; redundant, but cleaner
  4417.     
  4418. ;
  4419. ; We could check to see if the NDA is already open here and call _SelectWindow,
  4420. ; but (surprise!) OpenNDA does that for us!  So if you're one of those people who
  4421. ; based your NDA on Guillermo's original sample that returns an existing window
  4422. ; pointer if the NDA is already open, you've got dead code in there -- your open
  4423. ; routine isn't called if your NDA is already open.  Never has been.  It is on 
  4424. ; the Macintosh, though.
  4425. ;
  4426. ; 2.0a4 -- added InitCursor so the cursor is an arrow for the NDA's benefit.
  4427. ;
  4428.  
  4429.     _InitCursor    ; nice and polite-like
  4430.     
  4431.     pha    ; space for result
  4432.     pushword DANum    ; the ID of our NDA
  4433.     _OpenNDA
  4434.     pla    ; discard the reference number
  4435.     
  4436.     lda #0
  4437.     clc
  4438.     rts
  4439.     
  4440. *******************************************************************************
  4441. *
  4442. * UserIDToDAID takes a user ID in A and CDA = 1/NDA = 0 in X.
  4443. * It returns the DA's ID in A (for NDAs) or the DA's handle in X/Y (CDAs)
  4444. *
  4445. *******************************************************************************
  4446.     
  4447. UserIDToDAID    name
  4448.     sta TheID    ; keep this for reference
  4449.     txa
  4450.     clc
  4451.     ror a
  4452.     ror a    ; now old bit 0 == new bit 15
  4453.     sta CDANDAFlag
  4454.     
  4455.     lda #1
  4456.     sta DANum    ; starting count for our DA loop
  4457.     
  4458. @DAInfoLoop    pushword CDANDAFlag    ; NDAs are always referenced by index
  4459.     pushword #0
  4460.     pushword DANum
  4461.     pushword #38    ; always 38 bytes long
  4462.     pushlong #DAInfoBuffer
  4463.     _GetDeskAccInfo
  4464.         
  4465. @NoError    lda CDANDAFlag
  4466.     bmi @CheckCDA
  4467.     
  4468. @CheckNDA    lda NDAUserID
  4469. @CheckID    cmp TheID    ; is this what we're after
  4470.     beq @ThisIsIt
  4471.     inc DANum
  4472.     bra @DAInfoLoop
  4473.     
  4474. @CheckCDA    lda #0
  4475.     pha    ; space for result
  4476.     pha    ; don't change ID
  4477.     pushlong CDAHandle
  4478.     _SetHandleID    ; no change, returns old ID
  4479.     pla
  4480.     bra @CheckID
  4481.     
  4482. @ThisIsIt    lda CDANDAFlag
  4483.     bmi @FinishCDA
  4484.     
  4485. @FinishNDA    lda DANum
  4486.     ldx NDAHandle
  4487.     ldy NDAHandle+2
  4488.     rts
  4489.     
  4490. @FinishCDA    lda #0
  4491.     ldx CDAHandle
  4492.     ldy CDAHandle+2
  4493.     rts
  4494.     
  4495. ;
  4496. ; Private storage for OpenDAByUserID
  4497. ;
  4498.  
  4499. TheID    dc.w 0    ; the user ID we're working on
  4500. DANum    dc.w 0    ; index for which NDA we're asking about
  4501. CDANDAFlag    dc.w 0    ; are we asking about CDAs or NDAs?
  4502.  
  4503. DAInfoBuffer    dc.w 0    ; returned data size
  4504. NDAStatus    dc.w 0    ; nonzero indicates an open NDA
  4505. CDAHandle    equ NDAStatus
  4506. NDAOpen    dc.l 0    ; open routine
  4507. NDAClose    dc.l 0    ; close routine
  4508. NDAAction    dc.l 0    ; action routine
  4509. NDAInit    dc.l 0    ; init routine
  4510. NDAPeriod    dc.w 0    ; period
  4511. NDAEventMask     dc.w 0    ; event mask
  4512. NDATickCount    dc.l 0    ; tick count at last run event sent to DA
  4513. NDAWindPtr    dc.l 0    ; NDA's main window pointer, if any
  4514. NDAHandle    dc.l 0    ; NDA handle
  4515. NDAUserID    dc.w 0     ; NDA's user ID (finally!)
  4516.  
  4517.     EndP
  4518.     
  4519.     EJECT
  4520. *******************************************************************************
  4521. *
  4522. GiveMeMyFork    PROCNAME
  4523. *
  4524. * Description:    Returns quickly if our resource fork is already open.
  4525. *    If not, starts up the Resource Manager with our user
  4526. *    ID and opens our resource file.  Stores the resource file
  4527. *    number in the global variable IRResFile.
  4528. *
  4529. * Inputs:    None.
  4530. *
  4531. * Outputs:    Our resource file number in IRResFile.  Any GS/OS errors
  4532. *    in A with carry set, otherwise carry clear, A == $0000.
  4533. *
  4534. * External Refs:
  4535.     WITH IRData
  4536. *
  4537. * Entry Points:
  4538. *
  4539. *******************************************************************************
  4540.  
  4541. ;
  4542. ; If we get here, we're going to use resources, so save the current
  4543. ; resource application first for later restoration.
  4544. ;
  4545.     lda <OldResourceApp
  4546.     bne @GoodExit    ; if we're here, we're done!
  4547.  
  4548.     pha
  4549.     _GetCurResourceApp
  4550.     pla
  4551.     sta <OldResourceApp
  4552.     
  4553.     lda IRResFile
  4554.     bne @GoodExit
  4555.     
  4556. ; First, check the environment and see if we can do our thing.
  4557.  
  4558. @GSOSHere    lda >OS_BUSY
  4559.     bpl @WeCanGoOn
  4560.     bra @IRCantDoIt
  4561. @IRCantDoIt    lda #irGSOSNotAvail
  4562.     sec
  4563.     bra @rts
  4564.     
  4565. @WeCanGoOn    pushword IRUserID
  4566.     _ResourceStartUp    ; we're logged in now
  4567.     
  4568.     lda #0
  4569.     pha    ; space for result
  4570.     pushword #readEnable
  4571.     pha
  4572.     pha    ; map address == NIL
  4573.     pha
  4574.     pha    ; space for result
  4575.     pushword IRUserID
  4576.     pushword #$0001    ; file number one, always
  4577.     _LGetPathname2    ; leaves pointer to our file on stack
  4578.     _OpenResourceFile    ; opens our resource file
  4579.     pla
  4580.     bcs @rts
  4581.     
  4582.     sta IRResFile
  4583.     
  4584. @GoodExit    pushword IRUserID
  4585.     _SetCurResourceApp    ; redundant if we just started up
  4586.     
  4587.     lda #0
  4588.     clc
  4589. @rts    rts
  4590.     
  4591.     EndP
  4592.  
  4593.     EJECT
  4594. *******************************************************************************
  4595. *
  4596. IRNotifyProc    PROC
  4597. *
  4598. * Description:    This is our notification procedure; GS/OS calls us when
  4599. *    switching to P8 so we can close our resource file and
  4600. *    be aware of it.
  4601. *
  4602. *    Entry is PROC instead of PROCNAME because there's a
  4603. *    header we have to use.
  4604. *
  4605. *    We also call this from srqGoAway to shut down our
  4606. *    Resource Manager stuff.  Make sure to keep this in
  4607. *    mind if you ever change this routine.
  4608. *
  4609. *
  4610. * Inputs:    A,X,Y undefined
  4611. *
  4612. * Outputs:    None
  4613. *
  4614. * External Refs:
  4615.     WITH IRData
  4616. *
  4617. * Entry Points:
  4618.     ENTRY NotifyProcCode
  4619. *
  4620. *******************************************************************************
  4621.  
  4622.     dc.l 0
  4623.     dc.w 0    ; reserved
  4624.     dc.w $A55A    ; signature
  4625.     dc.l %10    ; switch GS/OS to P8 only
  4626. Event_code    dc.l 0    ; event code placed here
  4627.  
  4628. NotifyProcCode    NAME
  4629.  
  4630.     phb
  4631.     phk
  4632.     plb
  4633.     
  4634.     pha
  4635.     _GetCurResourceApp
  4636.     pla
  4637.     sta TempResourceApp    ; can't store on stack frame, but this
  4638.         ; routine isn't reentrant anyway
  4639.     lda IRUserID
  4640.     pha
  4641.     _SetCurResourceApp
  4642.     
  4643.     lda IRResFile
  4644.     beq @NotifyOut
  4645.     pha
  4646.     _CloseResourceFile
  4647.     
  4648.     lda #0
  4649.     sta IRResFile
  4650.     
  4651.     _ResourceShutDown
  4652.     
  4653.     lda TempResourceApp
  4654.     pha
  4655.     _SetCurResourceApp    ; restore this
  4656.  
  4657. @NotifyOut    plb
  4658.     rtl
  4659.     
  4660. TempResourceApp    dc.w 0
  4661.     
  4662.     EndP
  4663.     
  4664.     EJECT
  4665. *******************************************************************************
  4666. *
  4667. DoAlertWindow    PROCNAME
  4668. *
  4669. * Description:    Takes an AlertWindow resource ID in X and Y and displays
  4670. *    that alert.  Returns the button ID in A or $FFFF if 
  4671. *    something went wrong.
  4672. *
  4673. *    Verifies that the AlertWindow environment is present
  4674. *    before doing anything so callers don't have to worry
  4675. *    about that.
  4676. *
  4677. *
  4678. * Inputs:    AlertWindow resource ID in X and Y.
  4679. *
  4680. * Outputs:    Button ID in A, or $FFFF if something went wrong.
  4681. *
  4682. * External Refs:
  4683. *
  4684. * Entry Points:
  4685. *
  4686. *******************************************************************************
  4687.  
  4688.     phy
  4689.     phx    ; save these briefly
  4690.  
  4691.     pea 0    ; pre-zeroed
  4692.     _WindStatus
  4693.     pla
  4694.     bne @GetTheFork
  4695.     lda #$FFFF    ; something's wrong
  4696.     bra @rts    ; we can't play
  4697.  
  4698. @GetTheFork    jsr GiveMeMyFork
  4699.     
  4700.     pha
  4701.     pha    ; space for result
  4702.     _GetCursorAdr
  4703.     pulllong CursorAdr    ; save this locally
  4704.     
  4705.     _InitCursor
  4706.     
  4707.     plx
  4708.     ply
  4709.     
  4710.     lda #$FFFF
  4711.     pha    ; space for result
  4712.     pea $0034    ; string is resource, no sub strings,
  4713.         ; use new button placement, use sound
  4714.     pha
  4715.     pha    ; no substitution array
  4716.  
  4717.     phy
  4718.     phx    ; resource ID
  4719.     _AlertWindow
  4720.     
  4721.     pushlong CursorAdr
  4722.     _SetCursor
  4723.     
  4724.     pla
  4725.     
  4726. @rts    rts
  4727.  
  4728. CursorAdr    dc.l 0    ; temporary cursor address
  4729.     
  4730.     EndP
  4731.     
  4732.     END
  4733.  
  4734.  
  4735.  
  4736.